-1

I have section of code that updates a variable by the return of a Firebase query. Outside of this section, I reference that variable and print it.

However, it seems to be executing as a async operation and prints out the variable before it has any values put in so I keep getting null. Is there an on complete for addListenerForSingleValueEvent?

public Map<String, String> childKV;
public Map<String, Object> allChildren;
public getChild() {
    allChildren = new HashMap<>();
    DatabaseReference dbRef = fb.child("inventory");
    ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            for (DataSnapshot childSnap : snapshot.getChildren() {
                childKV = new HashMap<>();
                childKV.put(
                    childSnap.getKey(),childSnap.getValue()
                );
                allChildren.put(childSnap.getKey(), childKV);
            }
        }
        @Override
        ...
    };
    dbRef.orderByKey().addListenerForSingleValueEvent(listener);
    dbRef.removeEventListener(listener);
    printChildren(allChildren);
}
public void printChildren(Map<String,Object>) {...}

Edit:

Like Update value of variable from Firebase query? but for Java. Does this mean I have to use reflection?

1 Answers1

1

Indeed, the eventListeners have asynchronous behaviour and thus you have correctly understood your problem.

Unfortunately the solution I have 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", I would "when the data comes in, do my thing".

Meaning according to your problem, print the value inside the onDataChange() method of your singleValueEventListener, this would ensure that you don't get null and also you retrieve your value correctly.

Other than that, one more approach I found, when I searched though, is Task.await(). I won't be counting on it, but you may read more about that here:

StackOverflow Question

StackOverflow Answer

PradyumanDixit
  • 2,372
  • 2
  • 12
  • 20
  • My ```onDataChange()``` is getting fired for every child record (which equates to a row in the csv). But then it would only write one line over and over to the csv. I woud like to put the return value to a map, then write it. However, if I use ```map.put(snapshot.getValue())```, and put the write at the end, it would just write nulls. p.s. Is this the ```Task``` that was deprecated for ```ApiFuture```? – I should change my Username Nov 08 '18 at 10:01
  • Sorry but I didn't quite get what you want to do from your code, if you could provide your database structure and tell what you want to do, I may be of a bit more help :) – PradyumanDixit Nov 08 '18 at 10:52
  • @IshouldchangemyUsername if you found my answer useful, consider voting it up and marking it as correct, I'd appreciate that. Cheers! :) – PradyumanDixit Nov 10 '18 at 06:29