0

I've a simple database where I save the users of my application, like so:

firebase_database

I want to retrieve all the users_data.

I got the following User model:

public class User {
    private String name;
    private String email;
    private String uid;
    private String pass;

    public User() {

    }

    public User(String uid, String name, String email,  String pass) {
        this.name = name;
        this.email = email;
        this.uid = uid;
        this.pass = pass;
    }
//GETTERS & SETTERS//

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", uid='" + uid + '\'' +
                ", pass='" + pass + '\'' +
                '}';
    }
}

The problem is that i can't seem able to retrieve the data, I'm using the following method:

public ArrayList<User> listUsers() {
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference().child("users" + "/" + "users_data");
        final ArrayList<User> userArrayList = new ArrayList<>();


        myRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                User post = dataSnapshot.getValue(User.class);
                userArrayList.add(post);

                System.out.println(post);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("The read failed: " + databaseError.getCode());
            }
        });

        return userArrayList;
    }

But this returns an array of 0 elements. What am I doing wrong? If i change the DatabaseReference to one of the child the method returns 1 user. Any ideas?

KENdi
  • 7,576
  • 2
  • 16
  • 31

1 Answers1

1

addValueEventListener sets up an asynchronous call. onDataChange is guaranteed to not be invoked until long after your return statement is reached, making it return an empty arraylist. You simply can't use return types after asynchronous calls like you have.

In order to get your design to work, you need to input userArrayList into another method that is called in onDataChange. That way your method does stuff with your arraylist once it has been filled.

myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            User post = dataSnapshot.getValue(User.class);
            userArrayList.add(post);

            //Add
            Object.methodThatDoesSomething(userArrayList);
            //or
            Class.staticMethodThatDoesSomething(userArrayList);

            System.out.println(post);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getCode());
        }
    });

// Then don't do anything with userArrayList after this point because 
// it won't be populated yet.
Ryan Pierce
  • 1,583
  • 16
  • 24