Firestore into recyclerview using FirebaseUI, no data displayed - firebase

I just got started with Firestore. So I tried fitting my data directly into a recyclerview, here's the code I used for reference.
Here's my UserRecyclerView Fragment :
public class UserRecyclerView extends Fragment{
private ArrayList<User> user;
RecyclerView mRecyclerView;
public UserRecyclerView(){}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recycler_view,container,false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
FirestoreRecyclerAdapter adapter = getFirestoreRecyclerAdapter();
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
#NonNull
private FirestoreRecyclerAdapter getFirestoreRecyclerAdapter() {
Query query = FirebaseFirestore.getInstance()
.collection("users");
FirestoreRecyclerOptions<User> options = new FirestoreRecyclerOptions.Builder<User>()
.setQuery(query, User.class).build();
return new FirestoreRecyclerAdapter<User, UserViewHolder>(options) {
#Override
protected void onBindViewHolder(UserViewHolder holder, int position, User model) {
Log.d("USER", "DATA: "+model.getName());
holder.BindView(position, model);
}
#Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_list, parent, false);
return new UserViewHolder(view);
}
};
}
private class UserViewHolder extends RecyclerView.ViewHolder{
TextView info;
UserViewHolder(View itemView) {
super(itemView);
info = (TextView) itemView.findViewById(R.id.info_text);
}
void BindView(int position, User model){
info.setText(model.getName()+" , "+model.getId());
}
}
There's nothing in my MainActivity except for starting the above fragment. I don't know what's wrong with my code. It shows no errors, when I run the app it doesn't crash. It just enters into the recyclerview layout, I checked it by placing a textview field for being sure(now removed). I want you to help me out with the code. It's probably because of the adapter? Help me figure out. I have also uploaded a snippet of my database.
Thanks in advance!

Make sure you call startListening on the adapter to initiate the connection to Cloud Firestore, otherwise no data will be loaded.
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
See:
https://github.com/firebase/FirebaseUI-Android/blob/master/firestore/README.md#firestorerecycleradapter-lifecycle

Create recyclerview like below:
FirestoreRecyclerAdapter adapter = getFirestoreRecyclerAdapter();
//add below line
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

Related

Multiple class in Firebase, and when I get it by Recycler Adapter, the "adapter" declare in different if else statement. onStart and onStop not works

I am a newbie in Android Studio and I having some problem in Firebase Recycler Adapter. I got different database in Firebase and it follow to the user ID which is eBay(Example) and Kog. I want to work like if eBay having item, it will shows and else if Kog having item, it shows too. But in the code, I only declare adapter in if...else statement. This make onStart and onStop could not listening. Here is the code. Thanks all of you...
public RecyclerView recyclerView;
public RecyclerView.LayoutManager layoutManager;
FirebaseDatabase database;
DatabaseReference requests;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_history);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
database = FirebaseDatabase.getInstance();
requests = database.getReference("Users");
recyclerView = (RecyclerView)findViewById(R.id.order_history);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
loadOrders(common.currentUser.getUid());
}
private void loadOrders(String uid) {
DatabaseReference historyRef = FirebaseDatabase.getInstance().getReference("Users/orderHistory");
historyRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild("eBay")) {
FirebaseRecyclerAdapter<ebay_Order, orderViewHolder> adapter;
FirebaseRecyclerOptions<ebay_Order> options = new FirebaseRecyclerOptions.Builder<ebay_Order>()
.setQuery(requests.child(uid).child("eBay"), ebay_Order.class).build();
adapter = new FirebaseRecyclerAdapter<ebay_Order, orderViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull orderViewHolder holder, int position, #NonNull ebay_Order model) {
holder.txtOrderName.setText(model.getEbayId());
holder.txtOrderAmount.setText(model.getEbayAmount());
holder.txtOrderServices.setText(model.getOrderChoice());
}
#NonNull
#Override
public orderViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_history, parent, false);
return new orderViewHolder(view);
}
};
recyclerView.setAdapter(adapter);
}
if (snapshot.hasChild("KOG")){
FirebaseRecyclerAdapter<kog_Order, orderViewHolder> adapter;
FirebaseRecyclerOptions<kog_Order> options = new FirebaseRecyclerOptions.Builder<kog_Order>()
.setQuery(requests.child(uid).child("KOG"), kog_Order.class).build();
adapter = new FirebaseRecyclerAdapter<kog_Order, orderViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull orderViewHolder holder, int position, #NonNull kog_Order model) {
holder.txtOrderName.setText(model.getKogUsername());
holder.txtOrderAmount.setText(model.getKogAmounts());
holder.txtOrderServices.setText(model.getOrderChoice());
}
#NonNull
#Override
public orderViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_history, parent, false);
return new orderViewHolder(view);
}
};
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public void onBackPressed(){
Intent intent = new Intent(this, InterPayMain.class);
orderHistory.this.finish();
startActivity(intent);
}
And the code for order View Holder
public class orderViewHolder extends RecyclerView.ViewHolder {
public TextView txtOrderName, txtOrderAmount, txtOrderServices;
public LinearLayout root;
public orderViewHolder(#NonNull View itemView) {
super(itemView);
root = itemView.findViewById(R.id.list_root);
txtOrderName = itemView.findViewById(R.id.order_id);
txtOrderAmount = itemView.findViewById(R.id.order_amount);
txtOrderServices = itemView.findViewById(R.id.order_choice);
}
And the error is
error: cannot find symbol adapter.startListening();
Is that got anyway to declare adapter in begining and able to work for different class.
As mentioned in the answer to this question: How to set two adapters to one RecyclerView?, a single RecyclerView can have only one adapter. You can create an adapter that has two different ViewHolders and chooses between them via overriding getItemViewType - see the question I linked for more information on implementing that solution.
An alternative is to have two separate RecyclerViews: one for each of your lists (eBay and Kog).

Getting Data from firebase and binding to recycler view

First im using this version of database : implementation 'com.firebaseui:firebase-ui-database:6.2.1'
Im trying this code and getting error at the bold statement error is : Expected 1 arguments but found 4.
code is :
private void loadMenu() {
FirebaseRecyclerAdapter<Category, MenuViewHolder> adapter=new FirebaseRecyclerAdapter<Category, MenuViewHolder>**(Category.class,R.layout.menu_item,MenuViewHolder.class,category)** {
#Override
protected void onBindViewHolder(#NonNull MenuViewHolder holder, int position, #NonNull Category model) {
}
#NonNull
#Override
public MenuViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
}}
Edited one :
private void loadMenu() {
FirebaseRecyclerOptions<Category> options=new FirebaseRecyclerOptions.Builder<Category>()
.setQuery(category,Category.class)
.build();
FirebaseRecyclerAdapter adapter= new FirebaseRecyclerAdapter<Category, MenuViewHolder>(options) {
#NonNull
#Override
public MenuViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView= LayoutInflater.from(parent.getContext())
.inflate(R.layout.menu_item,parent,false);
return new MenuViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull MenuViewHolder viewHolder, int position, #NonNull Category model) {
viewHolder.txtMenuName.setText(model.getName());
Picasso.with(getBaseContext()).load(model.getImage())
.into(viewHolder.imageView);
final Category clickItem=model;
viewHolder.setItemClickListener...
}
}
};
}
public class MenuViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtMenuName;
public ImageView imageView;
private ItemClickListener itemClickListener;
public MenuViewHolder(#NonNull View itemView) {
super(itemView);
txtMenuName=(TextView)itemView.findViewById(R.id.menu_name);
imageView= (ImageView)itemView.findViewById(R.id.menu_image);
}
#Override
public void onClick(View view) {
}
}
The latest version (3.x) of FirebaseUI implements a different method of initializing a FirebaseRecyclerAdapter than previous versions. From the using the FirebaseRecyclerAdapter documentation:
First, configure the adapter by building FirebaseRecyclerOptions. In this case we will continue with our chat example:
FirebaseRecyclerOptions<Chat> options =
new FirebaseRecyclerOptions.Builder<Chat>()
.setQuery(query, Chat.class)
.build();
Next create the FirebaseRecyclerAdapter object. You should already have a ViewHolder subclass for displaying each item.
So, for your example, you'll need to do something similar to:
FirebaseRecyclerOptions<image_details> options =
new FirebaseRecyclerOptions.Builder<image_details>()
.setQuery(myRef, image_details.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<image_details, BlogViewHolder>(options) {
#Override
public BlogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.individual_row, parent, false);
return new BlogViewHolder(view);
}
#Override
protected void onBindViewHolder(BlogViewHolder holder, int position, image_details model) {
// Bind the image_details object to the BlogViewHolder
// ...
}
};
Finally, the FirebaseRecyclerAdapter uses an event listener to monitor changes to the Firebase query. To begin listening for data, call adapter.startListening() and adapter.stopListening() to stop the listener. It's recommended to call these in onStart() and onStop() respectively. Further details on this are available in the FirebaseRecyclerAdapter lifecycle documentation. taken from: firebaserecycleradapter() cannot be applied to FirebaseRecyclerAdapter

Using FirebaseUI for firebase recyclerView in android

i am a new comer in android development and facing some problems using firebase ui.
i wanted to retrieve data from my firebase database and show it on my recyclerView.
but i am constantly getting an error while making FirebaseRecyclerAdapter.
Here is My Code Sample:
public class UsersActivity extends AppCompatActivity {
private Toolbar userToolbar;
private RecyclerView usersList;
private DatabaseReference mUsersDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
userToolbar = (Toolbar) findViewById(R.id.users_toolbar);
setSupportActionBar(userToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Users");
mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
usersList = (RecyclerView) findViewById(R.id.users_list);
usersList.setHasFixedSize(true);
usersList.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Users, UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.single_user_list_layout,
UsersViewHolder.class,
mUsersDatabase
) {
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder holder, int position, #NonNull Users model) {
holder.setName(model.getName());
}
#NonNull
#Override
public UsersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
};
usersList.setAdapter(firebaseRecyclerAdapter);
}
public static class UsersViewHolder extends RecyclerView.ViewHolder
{
View mView;
public UsersViewHolder(#NonNull View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name)
{
TextView userNameView = (TextView) mView.findViewById(R.id.single_user_name);
userNameView.setText(name);
}
}
}
The Error i'm getting is this:
please help!!
Sorry wanted to comment but i ain't got enough points to do so.
Try this first, if it doesnt work try using FirebaseRecyclerOptions
(The latest version (3.x) of FirebaseUI implements a different method ofinitializing a FirebaseRecyclerAdapter than previous versions.)
Make your " firebaseRecyclerAdapter " variable global, so you would have something like this.
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.single_user_list_layout,
UsersViewHolder.class,
mUsersDatabase
)

How to use fake data to test RecyclerView?

I made my DataFakeGenerator to creat some fake datas to test my Recycelerview , but when i want to use it in one of my Fragments i have an error.
my error is in this line:
PostAdapter postAdapter = new PostAdapter(DataFakeGenerator.getData(this));
it says that i can not use "this",so what statement can i use in this parentheses?
here is my Fragment :
public class Frag_joke extends Fragment {
public static Fragment instance(){
Fragment fragment = new Frag_joke();
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup layout = (ViewGroup)inflater.inflate(R.layout.frag_joke,null);
RecyclerView recyclerView = (RecyclerView)layout.findViewById(R.id.recycler_view);
PostAdapter postAdapter = new PostAdapter(DataFakeGenerator.getData(this));
recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
recyclerView.setAdapter(postAdapter);
return layout;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}}
here is my DataFakeGenerator :
public class DataFakeGenerator {
public static List<Post> getData(){
List<Post> posts= new ArrayList<>();
for(int i=0;i<=6;i++){
Post post= new Post();
post.setId(i);
post.setContent("sample text");
posts.add(post);
}
return posts;
}}
and here is my PostAdapter:
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.PostViewHolder>{
private Context context;
private List<Post> posts;
public PostAdapter(Context context, List<Post>posts){
this.context = context;
this.posts = posts;
}
#Override
public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.layout_post,parent,false);
return new PostViewHolder(view);
}
#Override
public void onBindViewHolder(PostViewHolder holder, int position) {
Post post=posts.get(position);
holder.content.setText(post.getContent());
}
#Override
public int getItemCount() {
return posts.size();
}
public class PostViewHolder extends RecyclerView.ViewHolder{
private TextView content;
public PostViewHolder(View itemView) {
super(itemView);
content=(TextView)itemView.findViewById(R.id.post_content);
}}}
You are probably confused with your implementation. DataFakeGenerator.getData() does not need any parameter. It's your adapter constructor that has 2.
To create your adapter you can use the following instead:
PostAdapter postAdapter = new PostAdapter(getContext(), DataFakeGenerator.getData());
PS: this wouldn't work with the adapter creation (if that's the code you are actually trying to use), as the Fragment is not a context (but the Activity is, which is why you can access it with getContext() from the fragment
You can set preview on any cardview if you've. Let's you have a cardview name item_emergency_contact then, you can use tools:listitem="#layout/your_card_view"
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/contacts_recyclerView_emergency"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
tools:listitem="#layout/item_emergency_contact"
app:layout_constraintTop_toBottomOf="#+id/add_emergency_contacts" />

How do I Set TextFields from ParseQueryAdapter?

I have a ParseQueryAdapter that is populating a listview inside of a fragment:
QueryAdapter:
public class CustomAdapter extends ParseQueryAdapter implements AdapterView.OnItemClickListener {
public CustomAdapter(Context context) {
super(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery create() {
ParseQuery query = new ParseQuery("Invoice");
query.whereEqualTo("CustomerID", ParseUser.getCurrentUser());
return query;
}
});
}
#Override
public View getItemView(ParseObject object, View cellview, ViewGroup parent) {
if (cellview == null) {
cellview = View.inflate(getContext(), R.layout.cell_layout, null);
}
TextView cellDate = (TextView) cellview.findViewById(R.id.dateTextView);
TextView invoice = (TextView) cellview.findViewById(R.id.invoiceNoTextView);
cellDate.setText(object.getString("Date"));
invoice.setText(object.getString("InvoiceNumber"));
return cellview;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
}
Fragment Containing Listview:
public class InvoiceHistory extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout layout = (FrameLayout) inflater.inflate(R.layout.fragment_invoice_history, container, false);
ListView invoicesListView = (ListView) layout.findViewById(R.id.invoiceList);
ParseQueryAdapter adapter = new CustomAdapter(getActivity());
invoicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Fragment detailView = new InvoicesFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.placeholder, detailView);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
invoicesListView.setAdapter(adapter);
adapter.loadObjects();
return layout;
}
}
This populates the ListView with the proper fields from the query, but when I click on one of the cells the fragment transaction takes place, but i can't figure out how to set textfields on that new fragment with ParseObject Keys from the Query.
This is the fragment that gets Presented that I want to set the Textfields in:
public class InvoicesFragment extends Fragment {
public InvoicesFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.fragment_invoices, container, false);
return layout;
}
Android is super new to me so maybe this is a wrong way to approach it. But all i want to do here is have that detail fragment show up with populated TextViews. Im not really sure what I'm doing.
You could approach this by setting up a constructor in your DetailsFragment that you can pass in the textview info you want to show. In the example below, the data and invoice number are passed into the constructor. When the fragment is set up, this fragment is set up with the Parse object's data:
invoicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ParseObject object = adapter.getItem(i);
Fragment detailView = DetailsFragment.newInstance(object.getString("Date"),
object.getString("InvoiceNumber"));
// ...
}
});
Here's a portion of the DetailsFragment showing the new constructor as well as how you could use them in setting up your view:
// InvoicesFragment.java
public static class InvoicesFragment extends Fragment {
// ...
public static InvoicesFragment newInstance(String invoiceDate, String invoiceNumber) {
InvoicesFragment f = new InvoicesFragment();
Bundle args = new Bundle();
args.putString("invoiceDate", InvoiceDate);
args.putString("invoiceNumber", InvoiceNumber);
f.setArguments(args);
return f;
}
public String getInvoiceDate() {
return getArguments().getString("invoiceDate", "");
}
public String getInvoiceNumber() {
return getArguments().getString("invoiceNumber", "");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.fragment_invoices, container, false);
// Assign some TextView, ex: dateTextView
dateTextView.setText(getInvoiceDate());
return layout;
}
}

Resources