Reputation: 89
I am trying to get some data from Firebase from listener A, then I will search under a different node with listener B based on some ID obtained from listener A, and when I receive the data from listener B, I want to append it to listener A data. Basically I have 2 nodes in Firebase: posts & users. A post has some data, and a userID. When I want to display all posts in the database, I add each one to a RecyclerView, but before I add them to that View, I need to get some user data and only then (combinding these 2 gathered data) add it to the recyclerView.
I could not find anything onlineto try (other than some UI blocking things which I rather stay away as I am new to Android). I know Firebase is async and that Java does not have Promises or async/ await, so IDK what else to try. With my current implementation, I don't achieve what I want (obviously).
private void initialPopulatePostsFromDB(){
mDatabase.limitToFirst(2).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
List<IndividualPost> postsDB = new ArrayList<>();
for(DataSnapshot postSnapShot : dataSnapshot.getChildren()){
oldestPostId = postSnapShot.getKey();
final IndividualPost indivPost = postSnapShot.getValue(IndividualPost.class);
indivPost.setContents(typePostContents);
/*
FirebaseDatabase.getInstance().getReference("/users").child(indivPost.getUserId()).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
userAccount = dataSnapshot.getValue(UserAccount.class);
indivPost.setUserId(userAccount.getName());
System.out.println("[1] ACC NAME: " + indivPost.getUserId());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
*/
FirebaseDatabase.getInstance().getReference("/users").child(indivPost.getUserId()).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
userAccount = dataSnapshot.getValue(UserAccount.class);
indivPost.setUserId(userAccount.getName());
System.out.println("[1] ACC NAME: " + indivPost.getUserId());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
System.out.println("[2] ACC NAME: " + indivPost.getUserId());
postsDB.add(indivPost);
System.out.println("[3] ACC NAME: " + indivPost.getUserId());
}
posts.addAll(postsDB);
mAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
I expect to display new data, data from user combined with the post.
I expected to be printed:
[1] ACC NAME John
[2] ACC NAME John
[3] ACC NAME John
but it's actually
[2] BniepYpQuh6VgMF6L2
[3] BniepYpQuh6VgMF6L2
[1] John
Upvotes: 0
Views: 78
Reputation: 995
I expect to display new data, data from user combined with the post.
Reason you are not getting new data is because you are adding indivPost
to list and notifying recycle view in your first listener before getting user data in second listener.This way you can't achieve what you want because your for loop
is synchronous and listener is asynchronous. Change your firebase structure to store user's name with posts, So you don't have to make a second call to get usernames.
Upvotes: 1