Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve data from Firebase to my adapter

My structure

enter image description here

So I have an app in which users upload posts in my adapter. I can retrieve the post description and the post picture, but when I try to retrieve the poster's name the app seems to crash, to retrieve the name with every post there is a child added to the database with the uploader's id. This is my class file:

public String image_thumb;
public String user_id;
public String image_url;
public String desc;

public BlogPost(){}


public BlogPost(String user_id, String image_url, String desc, String image_thumb) {
    this.user_id = user_id;
    this.image_url = image_url;
    this.desc = desc;
    this.image_thumb = image_thumb;
}



public String getUser_id() {
    return user_id;
}

public void setUser_id(String user_id) {
    this.user_id = user_id;
}

public String getImage_url() {
    return image_url;
}

public void setImage_url(String image_url) {
    this.image_url = image_url;
}

public String getDesc() {
    return desc;
}

public void setDesc(String desc) {
    this.desc = desc;
}

public String getImage_thumb() {
    return image_thumb;
}

public void setImage_thumb(String image_thumb) {
    this.image_thumb = image_thumb;
}

and this is some of my adapter:

public void onBindViewHolder(final ViewHolder holder, int position) {

    String desc_data = blog_list.get(position).getDesc();
    holder.setDescText(desc_data);//this works

    String image_url = blog_list.get(position).getImage_url();
    holder.setBlogImage(image_url);//this works

    String user_id = blog_list.get(position).getUser_id();
    firebaseDatabase.child("Users").child(user_id).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists()){
                String userName = dataSnapshot.child("name").getValue().toString();

                holder.setUserName(userName);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    public void setUserName(String name){
        blogUserName = mView.findViewById(R.id.blog_user_name);
        blogUserName.setText(name);
    }

What I basically wanna do is look inside the user_id for the name and retrieve it inside my TextView

like image 953
R.Youssef Avatar asked Mar 20 '18 12:03

R.Youssef


People also ask

Can we retrieve data from Firebase?

Firebase data is retrieved by either a one time call to GetValueAsync() or attaching to an event on a FirebaseDatabase reference. The event listener is called once for the initial state of the data and again anytime the data changes.

Can Firebase store data locally?

The Firebase Realtime Database synchronizes and stores a local copy of the data for active listeners. In addition, you can keep specific locations in sync. The Firebase Realtime Database client automatically downloads the data at these locations and keeps it in sync even if the reference has no active listeners.


1 Answers

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();
    }
}
like image 64
Alex Mamo Avatar answered Oct 21 '22 23:10

Alex Mamo