Firebase - an attempt to extract the data of each user in a list

Each user in my application can send and receive requests from friends. When a user checks the requests of his friends, I want the application to go through each user who sent him a friendโ€™s request and retrieved his information from the Realtime Database .

This is my code to execute this:

  public void check_For_Friends_And_Requests(){ String loggedUser=SaveSharedPreference.getLoggedEmail(getApplicationContext()); final DatabaseReference mDatabase= FirebaseDatabase.getInstance().getReference(); final DatabaseReference userRef=mDatabase.child("Users").child(loggedUser); userRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { if (dataSnapshot.exists()){ final List<User> friendRequestsReceived_UserList=new ArrayList<>(); for (DataSnapshot postSnapshot: dataSnapshot.child("friend_requests_received").getChildren()) { final String senderEmail=postSnapshot.getKey(); Toast.makeText(getApplicationContext(), senderEmail, Toast.LENGTH_SHORT).show(); if (senderEmail!=null){ mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { Toast.makeText(getApplicationContext(), dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show(); friendRequestsReceived_UserList.add( new User( senderEmail, dataSnapshot.child("name").getValue(String.class), dataSnapshot.child("level").getValue(Integer.class), dataSnapshot.child("skill").getValue(Double.class))); } @Override public void onCancelled(DatabaseError databaseError) { } }); } } UserListAdapter friendRequestsReceived_Adapter = new UserListAdapter(getApplicationContext(), R.layout.friend_requests_received_listview_row, friendRequestsReceived_UserList); friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); } else connectionErrorGoToMain(); } @Override public void onCancelled(DatabaseError databaseError) { connectionErrorGoToMain(); } }); } 

I have 2 ValueEventListeners in this code. I am adding user information to the internal list. The problem is that the list is empty at the end of this process.

I would like to populate a list with this information using the following lines:

  UserListAdapter friendRequestsReceived_Adapter = new UserListAdapter(getApplicationContext(), R.layout.friend_requests_received_listview_row, friendRequestsReceived_UserList); friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); 

When I put them inside the internal listener, it works fine, but I do not want to install an adapter for each user in the list, only after the for loop.

I am attaching a screenshot to my database structure (I do not need to get all the parameters):

enter image description here

+5
source share
1 answer

The list is empty because you are declaring friendRequestsReceived_UserList outside the onDataChange() internal method. This is due to the asynchronous behavior of the onDataChange() method, which is called before you add these new objects to the list. So, to solve this problem, simply move the list declaration inside the onDataChange() internal method as follows:

 if (senderEmail!=null){ mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { final List<User> friendRequestsReceived_UserList=new ArrayList<>(); //Moved here Toast.makeText(getApplicationContext(), dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show(); friendRequestsReceived_UserList.add( new User( senderEmail, dataSnapshot.child("name").getValue(String.class), dataSnapshot.child("level").getValue(Integer.class), dataSnapshot.child("skill").getValue(Double.class))); UserListAdapter friendRequestsReceived_Adapter = new UserListAdapter(getApplicationContext(), R.layout.friend_requests_received_listview_row, friendRequestsReceived_UserList); friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); } @Override public void onCancelled(DatabaseError databaseError) { } }); 

As you probably see, I install the adapter also inside the internal method. If you want to use this list outside onDataChange() , I suggest you read my answer from.

+1
source

Source: https://habr.com/ru/post/1270609/


All Articles