How to iterate a node in Firebase database? - java

I've a simple database in Firebase like this:
The following code currently reads a resource fill and render each item read to a RecyclerView.
public class kos_putra extends Fragment {
ArrayList<Kost> mList = new ArrayList<>();
KostAdapter mAdapter;
DatabaseReference mFirebaseDatabase;
FirebaseDatabase mFirebaseInstance;
public kos_putra() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.kos_putra, container, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
mAdapter = new KostAdapter(mList);
recyclerView.setAdapter(mAdapter);
fillData();
return view;
}
private void fillData() {
Resources resources = getResources();
String[] arJudul = resources.getStringArray(R.array.places);
String[] arDeskripsi = resources.getStringArray(R.array.place_desc);
String[] arLokasi = resources.getStringArray(R.array.place_locations);
TypedArray a = resources.obtainTypedArray(R.array.places_picture);
Drawable[] arFoto = new Drawable[a.length()];
for (int i = 0; i < arFoto.length; i++) {
BitmapDrawable bd = (BitmapDrawable) a.getDrawable(i);
RoundedBitmapDrawable rbd =
RoundedBitmapDrawableFactory.create(getResources(), bd.getBitmap());
rbd.setCircular(true);
arFoto[i] = rbd;
}
a.recycle();
for (int i = 0; i < arJudul.length; i++) {
mList.add(new Kost(arJudul[i], arDeskripsi[i], arLokasi[i], arFoto[i]));
}
mAdapter.notifyDataSetChanged();
}
private void fetchDataFromFirebase(){
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseDatabase = mFirebaseInstance.getReference("kos_putra");
}
}
Now instead of reading from a file, I want to read from Firebase instead. How do I iterate each node under kos_putra? In the picture below, there are 4 objects. Logically, I'm thinking of getting the data count first, then do a for-loop. Still not clear how to do it, though.

To iterate in each node, do this:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("kos_putra");
ref.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot){
for(DataSnapshot data: dataSnapshot.getChildren()){
String deskripsi=data.child("deskripsi").getValue().toString();
String nama=data.child("nama").getValue().toString();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Here your datasnapshot is on kos_putra, add a listener on that location will iterate on all nodes(1,2,3,4) and with the for loop it will get the values that are inside all nodes also.

myRef.child("users").child(firebaseAuth.uid.toString()).addValueEventListener(object:ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
try {
var td=snapshot.value as HashMap<String,Any>
for(key in td.keys){
var userInfo=td[key] as String
if(key.equals("imageUrl")){
Picasso.get().load(userInfo).into(myView.imageProfilePhoto);
}else if(key.equals("name")){
myView.username.setText(userInfo)
}
}
}catch (ex:Exception){}
}
override fun onCancelled(error: DatabaseError) {
}
})

Related

I want to retrieve my firebase data into a card list, but not showing anything

I want to retrieve my firebase data into a card list, but not showing anything.
public class GroupAdp extends RecyclerView.Adapter<GroupAdp.ViewHolder> {
//Initialize activities and array list
private Activity activity;
ArrayList<String> arrayListGroup;
//Create constructor
GroupAdp(Activity activity,ArrayList<String> arrayListGroup){
this.activity = activity;
this.arrayListGroup = arrayListGroup;
notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_group,parent,false);
return new GroupAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set group name on TextView
holder.tvName.setText(arrayListGroup.get(position));
//Initialize member ArrayList
ArrayList<String> arrayListMember = new ArrayList<>();
//Using for loop to add multiple members
for (int i=1; i<=6; i++){
arrayListMember.add("Member " + i);
}
//Initialize member adapter
MemberAdp adapterMember = new MemberAdp(arrayListMember);
//Initialize layout manager
LinearLayoutManager layoutManagerMember = new LinearLayoutManager(activity);
//Set layout manager
holder.rvMember.setLayoutManager(layoutManagerMember);
//Set adapter
holder.rvMember.setAdapter(adapterMember);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
public class MemberAdp extends RecyclerView.Adapter<MemberAdp.ViewHolder> {
//Initialize ArrayList
ArrayList<String> arrayListMember;
//Create constructor
public MemberAdp(ArrayList<String> arrayListMember) {
this.arrayListMember = arrayListMember;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Initialize view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_member,parent,false);
return new MemberAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set member name on TextView
holder.tvName.setText(arrayListMember.get(position));
}
#Override
public int getItemCount() {
return arrayListMember.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
}
}
}
public class HealthAlertActivity2 extends Fragment {
//Initialize variable
RecyclerView rvGroup;
ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdp adapterGroup;
//#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View healthAlertFragment = inflater.inflate(R.layout.healthalert_activity2, container, false);
//Assign variable
rvGroup = healthAlertFragment.findViewById(R.id.rv_group);
//Using for loop to add multiple group
//Used for dummy display for now
arrayListGroup = new ArrayList<>();
// for (int i= 1; i<=6; i++){
// arrayListGroup.add("Group " + i);
// }
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Map<String, Object> map = (Map<String, Object>) snapshot.getValue();
Log.e("LOG_TAG", "Value is:" + map);
assert map != null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
Log.e("The Result", entry.getKey() + "/" + entry.getValue());
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
if (UID.equals(entry.getValue())) {
arrayListGroup.add("Class" + entry.getValue());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("LOG_TAG", "Failed to read value.", error.toException());
}
});
//Initialize group adapter
adapterGroup = new GroupAdp(getActivity(),arrayListGroup);
//Initialize layout manager
layoutManagerGroup = new LinearLayoutManager(getActivity());
//Set layout manager
rvGroup.setLayoutManager(layoutManagerGroup);
//Set adapter
rvGroup.setAdapter(adapterGroup);
return healthAlertFragment;
}
}
I want the Group name to be the Course_ID_Section, for example, CSCI-110-MO1. Only if the value inside of this key(CSCI-110-MO1) is the same as the firebase UID. Otherwise, perform no action.
Currently, I am dealing with this kind output:
E/LOG_TAG: Value is:{CSCI-110-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-415-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-455-M03={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-300-M02={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-318-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}}
E/The Result: CSCI-110-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
E/The Result: CSCI-415-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-455-M03/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-300-M02/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-318-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
Not sure if it is the "=" causing me the problem. Only want to compare firebase UID in this case.
You're loading data from:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
This means the snapshot you get has two nested, levels of dynamic nodes under it: the CSCI-110-M01 level, and then the level with the UIDs. So in your onDataChange you'll need two nested loops to iterate over both levels.
I'd also recommend iterating over the getChildren() of the snapshot, and only getting the values out of the snapshot at the lowest level.
Combined, that becomes:
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
for (DataSnapshot courseSnapshot: snapshot.getChildren()) {
for (DataSnapshot userSnapshot: courseSnapshot.getChildren()) {
if (UID.equals(userSnapshot.getKey())) {
arrayListGroup.add("Class" + userSnapshot.getValue(String.class));
}
}
}
}
...

Everything return into one list

I currently encounter an issue that everything returns to the same list. I know it is because I add everything into the same array. But how to add them to specific location like the one in my firebase.
public class GroupAdp extends RecyclerView.Adapter<GroupAdp.ViewHolder> {
//Initialize activities and array list
private Activity activity;
ArrayList<String> arrayListGroup;
MemberAdp adapterMember;
//Create constructor
GroupAdp(Activity activity,ArrayList<String> arrayListGroup){
this.activity = activity;
this.arrayListGroup = arrayListGroup;
// notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_group,parent,false);
return new GroupAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set group name on TextView
holder.tvName.setText(arrayListGroup.get(position));
//Initialize member ArrayList
ArrayList<String> arrayListMember = new ArrayList<>();
//Using for loop to add multiple members
// for (int i=1; i<=6; i++){
// arrayListMember.add("Member " + i);
// }
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
for (DataSnapshot courseSnapshot: snapshot.getChildren()) {
for (DataSnapshot userSnapshot: courseSnapshot.getChildren()) {
// arrayListMember.add(userSnapshot.getValue(String.class));
if(UID.equals(userSnapshot.getKey())) {
arrayListMember.add(userSnapshot.getValue(String.class));
}
}
}
adapterMember.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
//Initialize member adapter
adapterMember = new MemberAdp(arrayListMember);
//Initialize layout manager
LinearLayoutManager layoutManagerMember = new LinearLayoutManager(activity);
//Set layout manager
holder.rvMember.setLayoutManager(layoutManagerMember);
//Set adapter
holder.rvMember.setAdapter(adapterMember);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
public class HealthAlertActivity2 extends Fragment {
//Initialize variable
RecyclerView rvGroup;
ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdp adapterGroup;
//#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View healthAlertFragment = inflater.inflate(R.layout.healthalert_activity2, container, false);
//Assign variable
rvGroup = healthAlertFragment.findViewById(R.id.rv_group);
//Using for loop to add multiple group
//Used for dummy display for now
// for (int i= 1; i<=6; i++){
// arrayListGroup.add("Group " + i);
// }
ArrayList<String> arrayListGroup = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
Map<String, Object> map = (Map<String, Object>) snapshot.getValue();
Log.e("LOG_TAG", "Value:" + map);
assert map != null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
Log.e("The Result", entry.getKey());
arrayListGroup.add(entry.getKey());
}
adapterGroup.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("LOG_TAG", "Failed to read value.", error.toException());
}
});
//Initialize group adapter
adapterGroup = new GroupAdp(getActivity(), arrayListGroup);
//Initialize layout manager
layoutManagerGroup = new LinearLayoutManager(getActivity());
//Set layout manager
rvGroup.setLayoutManager(layoutManagerGroup);
//Set adapter
rvGroup.setAdapter(adapterGroup);
return healthAlertFragment;
}
}
public class MemberAdp extends RecyclerView.Adapter<MemberAdp.ViewHolder> {
//Initialize ArrayList
ArrayList<String> arrayListMember;
//Create constructor
public MemberAdp(ArrayList<String> arrayListMember) {
this.arrayListMember = arrayListMember;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Initialize view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_member,parent,false);
return new MemberAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set member name on TextView
holder.tvName.setText(arrayListMember.get(position));
}
#Override
public int getItemCount() {
return arrayListMember.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
}
}
}
Ideally, I want to return all students who have the same class as the user in the firebase and return them to different list based on how they are stored in firebase.
The thing is that you subscribe to the root of your data Course_ID_Section, so you get all the data in the same way without respect to its Courses ids. There are a few ways how to handle it, but in your case, I would recommend the following:
Store students not in the same array arrayListMember, but in Hashtable (or another associative array implementation), or in a new Course class. Then, fill in your new data structure when you are looping through courses in your line arrayListMember.add(userSnapshot.getValue(String.class)), because at this point you have a data about a student, and courseSnapshot to get the name of a course

RecyclerView Error No adapter attached ; skipping layout and setting OnClickListener

I'm working on an application where I store the data on Firebase and retrieve it after the user manages to sign in. The application works fine I see this error occurs.
E/RecyclerView: No adapter attached; skipping layout
I'm loading an image together with long and short description. I'm trying to take the users into another Activity where they can the content more detailed. However. I am confused where I can set OnClickListener so that I can take the id of this post and load it in another activity.
this is the main activity :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
homeAuth = FirebaseAuth.getInstance();
recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true); // this will load it from the end and show last as first
progressDialog = new ProgressDialog(this);
recyclerView.setLayoutManager(layoutManager);
postModelList = new ArrayList<>();
pullPosts();
}
and this is the method where I pull the data from the DB :
void pullPosts() {
progressDialog.setMessage("Please wait for the pictures to load...");
progressDialog.show();
progressDialog.setCancelable(false);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postModelList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()){
postModel = ds.getValue(PostModel.class);
postModelList.add(postModel);
postAdapter = new PostAdapter(HomeActivity.this , postModelList);
recyclerView.setAdapter(postAdapter);
}
progressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
progressDialog.dismiss();
Toast.makeText(HomeActivity.this, ""+databaseError, Toast.LENGTH_SHORT).show();
}
});
}
I read other posts related to that error tried the options but the rest seems to me fine as the following is my Adapter :
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.MyHolder> {
Context context;
List<PostModel> postModelList;
public PostAdapter(Context context, List<PostModel> postModelList) {
this.context = context;
this.postModelList = postModelList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.home_post, parent, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
String title = postModelList.get(position).getPostTitle();
String sDescription = postModelList.get(position).getPostShDescription();
String lDescription = postModelList.get(position).getPostLoDescription();
String image = postModelList.get(position).getPostImage();
holder.pulledTitle.setText(title);
holder.pulledShortDescription.setText(sDescription);
holder.pulledLongDescription.setText(lDescription);
Glide.with(context).load(image).into(holder.pulledImage);
//now we will add library to load image
}
#Override
public int getItemCount() {
return postModelList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
ImageView pulledImage;
TextView pulledTitle, pulledShortDescription, pulledLongDescription;
public MyHolder(#NonNull View itemView) {
super(itemView);
pulledImage = itemView.findViewById(R.id.pulled_image);
pulledTitle = itemView.findViewById(R.id.pulled_title);
pulledShortDescription = itemView.findViewById(R.id.pulled_short_description);
pulledLongDescription = itemView.findViewById(R.id.pulled_long_description);
}
}
}
Could you please help me with fixing the issue? I would appreciate your time and help.
E/RecyclerView: No adapter attached; skipping layout
that's not an error you can ignore it, it's happening because there's not adapter when the activity is created as you set the adapter after fetching the data.
About your question where to set onClickListener, you should do that in the adapter's viewHolder
class MyHolder extends RecyclerView.ViewHolder {
ImageView pulledImage;
TextView pulledTitle, pulledShortDescription, pulledLongDescription;
public MyHolder(#NonNull View itemView) {
super(itemView);
pulledImage = itemView.findViewById(R.id.pulled_image);
pulledTitle = itemView.findViewById(R.id.pulled_title);
pulledShortDescription = itemView.findViewById(R.id.pulled_short_description);
pulledLongDescription = itemView.findViewById(R.id.pulled_long_description);
itemView.setOnClickListner(v->{
//your implementation here f.e Id = postModelList.getId(); or and start another activity from here
});
}
}

Recycler view adapter now displaying data in fragment

I am trying to display data from my database in my fragment through recycler view. I used a for loop to go through all the users in my database. All the users who are neither friends nor have sent requests should be displayed as implemented in the if condition of fragment class. The code for fragment class is written below.
public class AddMemberFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private View view ;
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
String userId;
String n_team ;
ArrayList<Friend> friends;
public AddMemberFragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.addnewfriend_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
userId = firebaseUser.getUid();
ManageTeamTabbedActivity activity = (ManageTeamTabbedActivity) getActivity();
n_team = activity.getMyData();
mRecyclerView = (RecyclerView) getView().findViewById(R.id.addNewFriend);
//mRecyclerView.setHasFixedSize(true);//
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
friends = new ArrayList<>();
mAdapter = new AddMemberAdapter(getActivity(), friends, n_team) ;
mRecyclerView.setAdapter(mAdapter);
mRootRef.child("users");
mRootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Friend> friendArrayList = new ArrayList<>();
DataSnapshot friendsData = dataSnapshot.child(firebaseUser.getUid()).child("friends");
DataSnapshot requests = null;
DataSnapshot currentFriends = null;
if (friendsData.hasChild("requests")) {
requests = dataSnapshot.child(firebaseUser.getUid()).child("friends").child("requests");
}
if (friendsData.hasChild("currentFriends")) {
currentFriends = dataSnapshot.child(firebaseUser.getUid()).child("friends").child("currentFriends");
}
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
Log.d("demo", "USERID " + FirebaseAuth.getInstance().getCurrentUser().getUid());
Friend friend = new Friend();
if ((userSnapshot.getKey().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) || (requests != null && requests.hasChild(userSnapshot.getKey()))
|| (currentFriends != null && currentFriends.hasChild(userSnapshot.getKey()))) {
} else {
friend.setId(userSnapshot.getKey());
friend.setFriendName((String) userSnapshot.child("profiles").child("fname").getValue());
friendArrayList.add(friend);
}
}
friends = friendArrayList;
if (friends != null && !friends.isEmpty()) {
mAdapter.setFriendList(friends);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
And the corresponding adapter code is written here :
public class AddMemberAdapter extends RecyclerView.Adapter<AddMemberAdapter.RecyclerViewHolder>{
private ArrayList<Friend> mData;
private Context mContext;
private FirebaseAuth auth;
private String u_team ;
public AddMemberAdapter(Context mContext, ArrayList<Friend> friendList , String u_team) {
this.mData = friendList;
this.mContext = mContext;
this.u_team= u_team;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.addnewfriend_layout, parent, false);
AddMemberAdapter.RecyclerViewHolder viewHolder = new AddMemberAdapter.RecyclerViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
final Friend frnd =(Friend) mData.get(position);
holder.friendName.setText(frnd.getFriendName());
holder.addFriend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
frnd.setStatus("sent");
final DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final String UID = firebaseUser.getUid();
mRootRef.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mRootRef.child("users").child(UID).child("friends").child("requests").child(frnd.getId()).setValue(frnd);
Friend temp = new Friend();
temp.setId(firebaseUser.getUid());
temp.setFriendName(firebaseUser.getDisplayName());
temp.setStatus("received");
mRootRef.child("users").child(frnd.getId()).child("friends").child("requests").child(firebaseUser.getUid()).setValue(temp);
mData.remove(frnd);
notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
#Override
public int getItemCount() {
return mData.size();
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView friendName;
ImageButton addFriend;
public RecyclerViewHolder(View itemView) {
super(itemView);
friendName = (TextView)itemView.findViewById(R.id.textViewFriendName);
addFriend = (ImageButton) itemView.findViewById(R.id.imagebuttonFriendAdd);
}
}
public void setFriendList(ArrayList<Friend> friendList){
this.mData = friendList;
notifyDataSetChanged();
}
}
The output I am getting is attached here.
Users who are not friends and have not been sent friend requests by the current user should have been displayed in this Add New Member fragment through this RecyclerView. I tried to debug it myself and removed the if condition but it did not work either. Please guide how to display it. The
The database screenshot is attached as well.
I could not find a problem with your firebase query and the data-extraction techniques, however, with this data structure, as the list grows you will have a difficult time getting the list of your friends. From my understanding, it is just taking a lot of time to display the list in that fragment.
Also, you might consider setting up the adapter with the RecyclerView while you are initializing the RecyclerView.
You might consider doing something like the following.
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
userId = firebaseUser.getUid();
ManageTeamTabbedActivity activity = (ManageTeamTabbedActivity) getActivity();
n_team = activity.getMyData();
mRecyclerView = (RecyclerView) getView().findViewById(R.id.addNewFriend);
// mRecyclerView.setHasFixedSize(true); // Remove this line
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
// Set the adapter here with an empty list first.
friends = new ArrayList<>();
mAdapter = new AddMemberAdapter(getActivity(), friends, n_team);
mRecyclerView.setAdapter(mAdapter);
mRootRef.child("users");
mRootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Friend> friendArrayList = new ArrayList<>();
DataSnapshot friendsData = dataSnapshot.child(firebaseUser.getUid()).child("friends");
DataSnapshot requests = null;
DataSnapshot currentFriends = null;
if (friendsData.hasChild("requests")) {
requests = dataSnapshot.child(firebaseUser.getUid()).child("friends").child("requests");
}
if (friendsData.hasChild("currentFriends")) {
currentFriends = dataSnapshot.child(firebaseUser.getUid()).child("friends").child("currentFriends");
}
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
Log.d("demo", "USERID " + FirebaseAuth.getInstance().getCurrentUser().getUid());
Friend friend = new Friend();
if ((userSnapshot.getKey().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) || (requests != null && requests.hasChild(userSnapshot.getKey()))
|| (currentFriends != null && currentFriends.hasChild(userSnapshot.getKey()))) {
} else {
friend.setId(userSnapshot.getKey());
friend.setFriendName((String) userSnapshot.child("profiles").child("fname").getValue());
friendArrayList.add(friend);
}
}
friends = friendArrayList;
if (friends != null && !friends.isEmpty()) {
mAdapter.setFriendList(friends); // Set the friend list to the adapter when the list is loaded.
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
And in your adapter, you will need a function to set the friends' list and call notifyDataSetChanged().
// In your adapter class, add the following method.
public void setFriendList(ArrayList<Friend> friendList) {
this.mData = friendList;
notifyDataSetChanged();
}
I hope that helps.

How to wait for the data to be fetched from Firebase Database

I am trying to get recieverUID from a certain table and then get the Value of username cooresponding the UID from another table.
What I think is happening is that the Adapter is being set before the receivedNames Array List has been fetched as the App runs fine when I set the receivedName Array list as a constant.
Please tell me what's wrong here and if this is the correct way to do this
Here's what my database looks like,
Firebase DB
My code for Tab 3 Fragment
public class Tab3 extends Fragment {
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList<String> reminderMessages;
protected static ArrayList<String> receiverNames;
String senderUID;
private DatabaseReference mDatabase;
//Overriden method onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Change R.layout.tab1 in you classes
View v = inflater.inflate(R.layout.tab3, container, false);
//get current user
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
reminderMessages = new ArrayList<>();
receiverNames = new ArrayList<>();
senderUID = user.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child("reminders").orderByChild("senderUID").equalTo(senderUID);
//Setting size of recycler view as constant
recyclerView = (RecyclerView) v.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
//Setting Linear Layout
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//Getting message from database
String message = ds.child("reminderMessage").getValue(String.class);
//Adding database to ArrayList
reminderMessages.add(message);
//Getting ReceiverUID
String rUID = ds.child("receiverUID").getValue(String.class);
//Getting corresponding username of the ReceiverUID
GetName getName = new GetName();
getName.GetName(rUID);
reminderMessages.add(message);
// Log.d("String names", receiverNames.toString());
}
adapter = new DataAdapter(reminderMessages,receiverNames);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Error in Reaching Database
Toast.makeText(getContext(), "Something went Wrong!", Toast.LENGTH_SHORT).show();
}
});
//Returning the layout file after inflating
return v;
}
And here is my GetName Class
public class GetName {
private FirebaseAuth auth;
ListView listView;
private DatabaseReference mDatabase;
String receiverName;
public void GetName(String UID){
mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
Query query = mDatabase.orderByKey().equalTo(UID);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot2) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot users : dataSnapshot2.getChildren()) {
receiverName = users.child("username").getValue(String.class);
receiverNames.add(receiverName);
Log.d("name retrieved",receiverNames.toString());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
To solve this problem, please add the declaration of your receiverNames ArrayList inside the onDataChange() method, otherwise it will be null. This is happening due to asynchronous behaviour of that method. If you want to use those values outside that method, please see my answer from this post.

Categories

Resources