How can I retrieve data from Firebase to my adapter
In order to make it work correctly, I recommend you to do some changes in you model class as well as in your code. Your model class should look like:
public class BlogPost {
public String imageThumb, userId, imageUrl, desc;
public BlogPost() {}
public BlogPost(String imageThumb, String userId, String imageUrl, String desc) {
this.imageThumb = imageThumb;
this.userId = userId;
this.imageUrl = imageUrl;
this.desc = desc;
}
public String getImageThumb() {return imageThumb;}
public String getUserId() {return userId;}
public String getImageUrl() {return imageUrl;}
public String getDesc() {return desc;}
}
Please see the naming convention of the fields and getters.
In order to make it work, don't forget the remove the old data and add fresh one.
Assuming your have a .XML file for your activity that contains a RecyclerView
which looks like this:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"/>
And a .XML file for your item file, which looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/image_thumb_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/user_id_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/image_url_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/desc_text_view" />
</LinearLayout>
To display your data in a RecyclerView
using a FriebaseRecyclerAdapter
, please follow the next steps:
First, you need to find the RecyclerView
in your activity and set the LinearLayoutManager
like this:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Then you need to create the root reference of your Firebase database and a Query
object like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users");
Then you'll have to create a FirebaseRecyclerOptions
object like this:
FirebaseRecyclerOptions<BlogPost> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<BlogPost>()
.setQuery(query, BlogPost.class)
.build();
In your activity class, create a holder
class that looks like this:
private class BlogPostHolder extends RecyclerView.ViewHolder {
private TextView imageThumbtextView, userIdTextView, imageUrlTextView, descTextView;
BlogPostHolder(View itemView) {
super(itemView);
imageThumbtextView = itemView.findViewById(R.id.image_thumb_text_view);
userIdTextView = itemView.findViewById(R.id.user_id_text_view);
imageUrlTextView = itemView.findViewById(R.id.image_url_text_view);
descTextView = itemView.findViewById(R.id.desc_text_view);
}
void setBlogPost(BlogPost blogPost) {
String imageThumb = blogPost.getImageThumb();
imageThumbtextView.setText(imageThumb);
String userId = blogPost.getUserId();
userIdTextView.setText(userId);
String imageUrl = blogPost.getImageUrl();
imageUrlTextView.setText(imageUrl);
String desc = blogPost.getDesc();
descTextView.setText(desc);
}
}
Then create an adapter which is declared as global:
private FirebaseRecyclerAdapter<BlogPost, BlogPostHolder> firebaseRecyclerAdapter;
And instantiate it in your activity like this:
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<BlogPost, BlogPostHolder>(firebaseRecyclerOptions) {
@Override
protected void onBindViewHolder(@NonNull BlogPostHolder blogPostHolder, int position, @NonNull BlogPost blogPost) {
blogPostHolder.setBlogPost(blogPost);
}
@Override
public BlogPostHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new BlogPostHolder(view);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
In the end, don't forget to override the following two methods and start listening for changes:
@Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
if (firebaseRecyclerAdapter!= null) {
firebaseRecyclerAdapter.stopListening();
}
}
Its better to not include any firebase calls inside your ViewBinder for recycler view. What you can do is update your BlogPost and include a field name with getter and setter. Then inside your activity where you are adding the BlogPost to the recycler adapter you can fetch the user name add the name to the blog post and notify adapter of data change.
In your activity do this
// adding BlogPost to list
// Create BlogPost object with the data.
blogList.add(blogPostObject)
firebaseDatabase.child("Users").child(user_id).child("name").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
blogPostObject.setName(dataSnapshot.getValue().toString());
adapter..notifyItemChanged(indexOfblogPostObject);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
The code below goes inside onBindviewhoder() under this line:
String user_id = . . .. . . .
I guess its the way you refer to your data and the way you attach the listener. Try to initialize the database ref like this:
DatabaseReference firebaseDatabase= FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
and now try to listen like this:
firebaseDatabase.addValueEventListener(new ValueEvent....{
onDataChange(.....){
//your same code
}
})