首页 > 解决方案 > Completion handler or equivalent in Android

问题描述

So I have a question in regards to getting data from Firebase Realtime DB for Android, as it seems that completion handlers are not possible as is in iOS.

I would like to gather a list of users and their status in a particular group they are part of. My Firebase DB is structured as such:

UserInGroup
   --- GroupID
          --- UserId : true/false     (true indicates user is in the group)


Users
   --- UserId
          --- Username : String
          --- ...


GroupStatus
   --- GroupId
          --- UserId: true/false      (true indicates has admin rights)

Based on the above I would like to have a Table where it will list the user's "username" followed by the status of either admin or normal user in the group.

My code I have so far to perform the first portion of the lookup is below:

    userInGroupReference = mFirebaseDatabase.getReference("UserInGroup");

    userInGroupQuery = userInGroupReference.child("10263").orderByValue().equalTo(true);

    userInGroupQuery.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for (DataSnapshot resultSnapshot : dataSnapshot.getChildren()) {

                    // THIS IS WHERE I AM GETTING THE USERS ID (KEY) TO THE OTHER TWO LOOKUPS I NEED TO PERFORM
                    String userID = resultSnapshot.getKey();

                    ... What do I do now with no completion handlers!?
                }
            } else { 
                // dataSnapshot doesn't exist
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

I am just confused on how to utilize the userID I get from the first lookup and perform the additional two lookups using the userID in android!?

I mean if it was iOS I would just use completion handlers to accomplish this... how can I do so in Android?

UPDATE:

I created the interface:

private interface FirebaseCallback {

    void onSuccess(DataSnapshot dataSnapshot);

    void onStart();

    void onFailure();

}

Then created the readData function

private void readData(Query query, FirebaseCallback listener) {

    listener.onStart();

    query.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            if (dataSnapshot.exists()) {

                listener.onSuccess(dataSnapshot);

            } 

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

}

And placed the readData function in my OnCreate function in the Activity as such:

readData(userInGroupQuery, new FirebaseCallback() {

    @Override
    public void onSuccess(DataSnapshot dataSnapshot) {

        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {

            String userId = snapshot.getKey();   

            // Get userId data from database....now you can use the retrieved data
            getUsername(userId);

            getUserStatus(userId);

        }

    }

    @Override
    public void onStart() {

        // When starting
        Log.d("ONSTART", "Started");

    }

    @Override
    public void onFailure() {

        // If failed
        Log.d("onFailure", "Failed");

    }

});

So now my question is when I call the following two (2) functions:

// Get userId data from database....now you can use the retrieved data
    getUsername(userId);

    getUserStatus(userId);

how do I get the values for for each iteration I send over for the second lookup in Firebase?

2ND UPDATE:

public void getUsername(String userId) {
    
    userReference = mFirebaseDatabase.getReference("Users");

    userQuery = userReference.child(userId).child("username");

    userQuery.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            if (dataSnapshot.exists()) {

                String username = dataSnapshot.getValue().toString();

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

}

and the last lookup:

private void getUserStatus(String userId) {

    statusQuery.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            if (!dataSnapshot.exists()) {

                Boolean status = (Boolean) dataSnapshot.getValue();

            }
            
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });
    
}

My goal is to have the values of the two look-ups populate a List

List<UserResults> userList;

public class UserResults {


    private String username;
    private boolean status;

    public UserResults(String username, boolean status) {

        this.username = username;
        this.status = status;

    }

}

Which is the part I am stuck on now.

标签: androidfirebasefirebase-realtime-database

解决方案


推荐阅读