ArrayList not updating inside onChildAdded function

前端 未结 1 871
不思量自难忘°
不思量自难忘° 2020-12-02 03:24
public class DataService {

    private static DataService ourInstance = new DataService();
    private DatabaseReference mDatabase;


    public static DataService          


        
相关标签:
1条回答
  • 2020-12-02 03:29

    Data is loaded and synchronized from Firebase asynchronously.

    It's easiest to see what's causing your problem if you add a few well-placed logging statements:

    public ArrayList<UserDatabase> getFriendList() {
    
        mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
        final ArrayList<UserDatabase> list = new ArrayList<>();
    
        System.out.println("Attaching listener");
        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                System.out.println("Got data");
            }
    
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
            public void onChildRemoved(DataSnapshot dataSnapshot) {}
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
            public void onCancelled(DatabaseError databaseError) {}
        });
    
        System.out.println("Returning list");
        return list;
     }
    

    The output will print in this order:

    Attaching listener

    Returning list

    Got data

    That is probably not the order you expected. But it does explain why the list of empty if you run the code as is.

    The reason for this is that Firebase loads and synchronizes the data asynchronously. Like most modern web APIs it doesn't wait for the result to return (that would lead to a horrible user-experience), but instead lets the program continue and calls back into your code when it gets (new) data.

    The way to deal with this behavior is to reframe the flow of your program from "first get the list of friends, then do xyz with it" to "whenever the list of friends changes, do xyz with it".

    For example say that you simply want to print how many friends there are. Your current approach is probably:

    ArrayList<UserDatabase> friends = getFriendList();
    System.out.println("There are "+friends.size()+" friends");
    

    With Firebase one way to handle this is to move the operation into getFriendList():

    public void getFriendList() {
    
        mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
        final ArrayList<UserDatabase> list = new ArrayList<>();
    
        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                UserDatabase userDatabase = dataSnapshot.getValue(UserDatabase.class);
                list.add(userDatabase);
                System.out.println("There are "+friends.size()+" friends");
            }
    
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
            public void onChildRemoved(DataSnapshot dataSnapshot) {}
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
            public void onCancelled(DatabaseError databaseError) {}
        });
    
     }
    
    0 讨论(0)
提交回复
热议问题