Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase - Trying to retrieve data of each user into a list

Each user in my app can send and get friend requests. When the user checks his friends requests, I want the app to go through each user who sent him a friend request and retrieve his information from the Realtime Database.

This is my code in order to accomplish 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 in this code 2 ValueEventListeners. I add the user information to the list in the inner one. The problem is that the list is empty at the end of this process.

I would like to fill a list view with this information using these 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 innner listener, it works fine, but I don't want to set the adapter for each user in the list, only after the for loop.

I'm attaching a screenshot with my database structure (I don't need to get all of the parameters):

enter image description here

like image 239
Tal Barda Avatar asked Nov 08 '22 18:11

Tal Barda


1 Answers

The list is empty because you are declaring friendRequestsReceived_UserList outside the inner onDataChange() method. This is happening due the asynchronous behaviour of onDataChange() method which is called before you are adding those new objects to the list. So, in order to solve this, just move the declaration of the list inside the inner onDataChange() method like this:

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 set the adapter also inside the inner method. If you want to use that list outside the onDataChange() i suggest you reading my answer from this post.

like image 73
Alex Mamo Avatar answered Nov 15 '22 08:11

Alex Mamo