Reputation: 21
I have a problem with getting my data from Firebase Database into RecyclerView in my App. I want to get data from UserUid child into separeted CardViews, but I get only one CardView with the last data child in the Database. I've watched a tutorial on YouTube, but there wasn't anything given about getting data with dataSnapshot. I suppose that I should do it using Array for the data, because I get all my data in Log, but don't know how to do it. Please help and explain. Thanks beforehand.
ViewDatabase.class
package com.mcarrow.mapsservicerunning;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class ViewDatabase extends AppCompatActivity {
private static final String TAG="ViewDatabase";
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private RecyclerView mBlogList;
private String userID;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_database_layout);
mAuth=FirebaseAuth.getInstance();
mFirebaseDatabase= FirebaseDatabase.getInstance();
myRef=mFirebaseDatabase.getReference("users");
myRef.keepSynced(true);
mBlogList=(RecyclerView)findViewById(R.id.myrecycleview);
mBlogList.setHasFixedSize(true);
mBlogList.setLayoutManager(new LinearLayoutManager(this));
FirebaseUser user=mAuth.getInstance().getCurrentUser();
userID=user.getUid();
mAuthListener=new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user =firebaseAuth.getInstance().getCurrentUser();
if(user!=null){
Log.d(TAG,"Signed in"+user.getUid());
toastMessage("Signed In"+user.getEmail());
}else {
Log.d(TAG,"Signed Out");
toastMessage("Signed Out");
}
}
};
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void showData(DataSnapshot dataSnapshot) {
final DataSnapshot contactSnapshot=dataSnapshot.child(userID);
final FirebaseRecyclerAdapter<UserInformation, BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<UserInformation, BlogViewHolder>(UserInformation.class, R.layout.blog_row, BlogViewHolder.class, myRef) {
@Override
protected void populateViewHolder(BlogViewHolder viewHolder, UserInformation model, int position) {
Iterable<DataSnapshot>contactChildren=contactSnapshot.getChildren();
for (DataSnapshot contact : contactChildren) {
UserInformation uInfo = new UserInformation();
uInfo.setTitle(contact.getValue(UserInformation.class).getTitle());
uInfo.setDesc(contact.getValue(UserInformation.class).getDesc());
viewHolder.setTitle(uInfo.getTitle());
Log.d(TAG, "viewHolder " + uInfo.getTitle());
viewHolder.setDesc(uInfo.getDesc());
}
}
};
mBlogList.setAdapter(firebaseRecyclerAdapter);
}
public static class BlogViewHolder extends RecyclerView.ViewHolder{
View mView;
public BlogViewHolder(View itemView){
super(itemView);
mView=itemView;
}
public void setTitle(double title){
TextView post_title=(TextView)mView.findViewById(R.id.post_title);
post_title.setText(""+title);
}
public void setDesc(String desc){
TextView post_desc=(TextView)mView.findViewById(R.id.post_desc);
post_desc.setText(desc);
}
}
@Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
protected void onStop() {
super.onStop();
if(mAuthListener!=null){
mAuth.removeAuthStateListener(mAuthListener);
}
}
private void toastMessage(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
UserInformation.class
package com.mcarrow.mapsservicerunning;
public class UserInformation {
private double title;
private String desc;
public UserInformation(double title, String desc) {
this.title = title;
this.desc = desc;
}
public double getTitle() {
return title;
}
public void setTitle(double title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public UserInformation(){
}
}
Upvotes: 0
Views: 53
Reputation: 632
You should set the adapter in the Activity's onCreate method. You should also create a custom adapter to display the items as you want.
Your activity class:
RecyclerView studyGroupsRV;
LayoutManager layoutManager;
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_database_layout);
// declare view variables ...
studyGroupsRV = context.findViewById(R.id.studyGroupsRV);
dbStudyGroups = FirebaseDatabase.getInstance().getReference().child("studyGroups");
// Set the event listener:
dbStudyGroups.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
// This will be called as many times as many items have you
studyGroupsAdapter.addStudyGroup(new StudyGroup(
dataSnapshot.getKey(),
dataSnapshot.child("title").getValue().toString(),
dataSnapshot.child("description").getValue().toString(),
dataSnapshot.child("age").getValue().toString(),
dataSnapshot.child("room").getValue().toString(),
dataSnapshot.child("time").getValue().toString()
));
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
// You can handle here the item changes
}
// Removes the deleted item from the adapter's dataset
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
studyGroupsAdapter.removeStudyGroupByKey(dataSnapshot.getKey());
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
// ...
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
// You can handle here the errors
}
});
StudyGroupsAdapter studyGroupsAdapter = new StudyGroupsAdapter(this, new ArrayList<>());
layoutManager = new LinearLayoutManager(this);
studyGroupsRV.setAdapter(studyGroupsAdapter);
studyGroupsRV.setLayoutManager(layoutManager);
studyGroupsRV.setItemAnimator(new DefaultItemAnimator());
Then you can create your own Adapter class:
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class StudyGroupsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int TYPE_STUDY_GROUP = 1;
private static final int TYPE_HEADER = 0;
private static ArrayList<StudyGroup> studyGroups;
private Context context;
private LayoutInflater inflater;
private Holder<Boolean> isOpenedPost;
/**
* Constructor
*
* @param context
* @param studyGroups
*/
public StudyGroupsAdapter(Context context, ArrayList<StudyGroup> studyGroups) {
this.context = context;
this.studyGroups = studyGroups;
inflater = LayoutInflater.from(context);
isOpenedPost = new Holder<>(false);
}
/**
* Gets the data list
*/
public static ArrayList<StudyGroup> getStudyGroups() {
return studyGroups;
}
/** Set the dataset */
public void setStudyGroups(ArrayList<StudyGroup> studyGroups) {
this.studyGroups = studyGroups;
notifyDataSetChanged();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// You can create multiple types of views
return new StudyGroupHolder(inflater.inflate(R.layout.study_group_row, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder_, int position) {
StudyGroupHolder holder = (StudyGroupHolder) holder_;
holder.title.setText(studyGroups.get(position).getTitle());
holder.excerpt.setText(studyGroups.get(position).getDescription());
holder.time.setText(studyGroups.get(position).getTime());
}
}
/**
* Get the size of the RecyclerView List
*
* @return the size of the list
*/
@Override
public int getItemCount() {
return studyGroups.size();
}
// You can add an item to the list by this method (in firebase onChildAdded event)
public void addStudyGroup(StudyGroup studyGroup) {
studyGroups.add(studyGroup);
notifyDataSetChanged();
}
// It removes all the items from the dataset (and the list)
public void removeStudyGroups() {
studyGroups.clear();
notifyDataSetChanged();
}
// Removes an item by friebase key (You can call it from firebase onChildRemoved event)
public void removeStudyGroupByKey(String key) {
for (int i = 0; i < studyGroups.size(); i++) {
if (studyGroups.get(i).getKey().equals(key)) {
studyGroups.remove(i);
}
}
notifyDataSetChanged();
}
private class StudyGroupHolder extends RecyclerView.ViewHolder {
TextView title;
TextView excerpt;
TextView time;
Button readMoreButton;
public StudyGroupHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.studyGroupTitle);
excerpt = itemView.findViewById(R.id.studyGroupDescription);
time = itemView.findViewById(R.id.studyGroupTime);
readMoreButton = itemView.findViewById(R.id.SGreadMoreBtn);
}
}
}
Upvotes: 1