1

I am trying to read my firebase data into a list of events. Since the firing of value event listener is asynchronous I tried to encapsulate the List I want returned inside this task.

Task<List<Event>> task = Tasks.call(new ReturnEventList(mDatabaseRef.child("Events")));
    task.addOnSuccessListener(new OnSuccessListener<List<Event>>() {
        @Override
        public void onSuccess(List<Event> events) {
            Log.i(TAG,"size " + events.size());
            for (Event event : events) {
                Log.i(TAG,event.toString());
            }
        }
    });

ReturnEventList:

class ReturnEventList implements Callable<List<Event>> {

private static final String TAG = "ReturnEventList";

DatabaseReference mDatabaseRef;

public ReturnEventList(DatabaseReference mDatabaseReference) {
    this.mDatabaseRef = mDatabaseReference;
}

@Override
public List<Event> call() throws Exception {
    List<Event> events = new ArrayList<>();
    mDatabaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(TAG,dataSnapshot.toString());
            for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                Log.i(TAG,childSnapshot.toString());
                Event event = childSnapshot.getValue(Event.class);
                events.add(event);
                Log.i(TAG,event.toString());
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
    return events;
}

The log statements inside returnEventList prints correctly and I'm able to get the list of events that I want. However when I add a onSuccessListener the size I print returns me 0. The list is practically empty. Not sure what is going on here ?

ReyAnthonyRenacia
  • 17,219
  • 5
  • 37
  • 56
calveeen
  • 621
  • 2
  • 10
  • 28
  • Please check **[this](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)**. out. Will help you understand the concept. – Alex Mamo Aug 03 '18 at 09:16

1 Answers1

2

addListenerForSingleValueEvent() is asynchronous, meaning it returns immediately, while it's callbacks will be invoked some unknown time later. Your code is currently expecting that it returns only after data is received, which is never going to happen.

Your code should be restructured to use asynchronous programming rather than assuming everything will execute in the order of the lines of code that you see.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Do you have any suggestions on how to read firebase data into the list and be able to use the result . I thought value event listener is the only way to read the data from firebase – calveeen Aug 03 '18 at 04:01
  • Only use the result of the query from within the callback itself, or a function it invokes. Don't just stuff the results in some member or global variable and expect that some other code will be able to make use of it. – Doug Stevenson Aug 03 '18 at 04:02
  • What do you mean by within the callback? Where is the callback for value event listener ? – calveeen Aug 03 '18 at 04:04
  • The callback is your `new ValueEventListener`. – Doug Stevenson Aug 03 '18 at 04:04
  • All right but isn’t fire base task supposed to handlr async computations so that you can get the result of it after it completes on another thread ? – calveeen Aug 03 '18 at 04:10
  • There is no Task in play in your situation. – Doug Stevenson Aug 03 '18 at 04:12