Indeed, the eventListeners
and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange()
of valueEventListener
, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null
if you haven't initialised it to something else. So all further operations that you do, occur on null
.
So it would be better for you to execute your method or code inside the valueEventListener
itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await()
. But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer