ArrayList not updating inside onChildAdded function

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) {}
    });

 }