Retrieving Data from a Database Returning NULL

When I call listPost () it returns NULL. I guess he didn't wait for the listener to receive the message from firebase. How can I wait to receive a message from firebase before arrayPost returns?

public Post[] listPost() {
    ArrayList<Post> list = new ArrayList<Post>();

    // Fetch post from firebase
    postRef.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot snapshot) {
            for(DataSnapshot child : snapshot.getChildren()) {
                String id = child.getKey();
                String title = child.child("title").getValue().toString();
                String content = child.child("content").getValue().toString();
                String date = child.child("date").getValue().toString();
                String status = child.child("status").getValue().toString();

                Post post = new Post();
                post.setId(id);
                post.setTitle(title);
                post.setContent(content);
                post.setDate(date);
                post.setStatus(status);
                list.add(post);
            }
        }

        @Override
        public void onCancelled(FirebaseError error) {
            System.out.println("The read failed: " + error.getMessage());
        }
    });

    // Convert ArrayList to Array 
    Post[] arrayPost = new Post[list.size()]; 
    list.toArray(arrayPost);
    return arrayPost;
}

      

+3


source to share


1 answer


While you can turn listPost()

into a synchronous method using something like semaphores, that doesn't mean Firebase is designed to work. For example, every time you call addValueEventListener()

, it adds a new listener that will be called whenever your data changes once, every time you call listPost()

.

If the purpose of a method listPost()

is to update some state somewhere (like your user interface), you can instead update the state directly from your method onDataChanged()

. This will ensure that you only add one event listener, the values ​​and updates in your data will always appear in your current state without needing to be updated.



// Setup once when your app loads
postRef.addValueEventListener(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot snapshot) {
        ArrayList<Post> list = new ArrayList<Post>();
        for(DataSnapshot child : snapshot.getChildren()) {
            String id = child.getKey();
            String title = child.child("title").getValue().toString();
            String content = child.child("content").getValue().toString();
            String date = child.child("date").getValue().toString();
            String status = child.child("status").getValue().toString();

            Post post = new Post();
            post.setId(id);
            post.setTitle(title);
            post.setContent(content);
            post.setDate(date);
            post.setStatus(status);
            list.add(post);
        }
        // Do something with your list of posts here
        updateSomething(list);
    }

    @Override
    public void onCancelled(FirebaseError error) {
        System.out.println("The read failed: " + error.getMessage());
    }
});

      

Since you have a list of children, here you can also use ChildEventListener

here and react to added child, child and child remote events to update your state or UI.

+3


source







All Articles