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;
}
source to share
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.
source to share