Wait Until Firebase Retrieves Data

Firebase Realtime Database wait until the data is retrieved

You can achieve it using this way by utilizing the Task. Tasks.whenall() will wait until all task are done.

fun functionA() {

val taskList = mutableListOf<Task<DataSnapshot>>()
val resultFileDataList = List<DataSnapshot>()

for ((key, value) in filesMap) {
val databaseReferenceTask: Task<DataSnapshot> = database.child("files").child(key).get()
taskList.add(databaseReferenceTask)

val resultTask = Tasks.whenAll(taskList)
resultTask.addOnCompleteListener {
for (task in taskList) {
val snapshotKey: String? = task.result.key
val snapShotValue = task.result
}

callFunctionB()
}
}
}

How to wait for Firebase Task to complete to get result as an await function

Data is loaded from Firebase asynchronously, since it may have to come from the server. While the data is being loaded, your main code continues to run. Then when the data is available, the task completes and your onSuccess gets called.

It's easiest to see what this means in practice by running in a debugger, or by adding some logging:

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
Log.i("Firebase", "1. Starting to load data");
Task<DataSnapshot> dataSnapshotTask = mDatabase.get();
for (DataSnapshot parking: parkingsData) {
Log.i("Firebase", "2. Got data");
}
Log.i("Firebase", "3. After starting to load data");

When you run this code, it prints:

  1. Starting to load data

  2. After starting to load data

  3. Got data

This is probably not the order that you expected, but it actually working as intended. It also explains why you're not getting a result from your getParkingLots function: by the time your return parkings runs, the parkings.add(parking.getValue(Parking.class)) hasn't been called yet!


The solution for this is always the same: any code that needs the data from the database, needs to be inside your onSuccess method or be called from there. This means you can't return the parking lots from the function, but you can pass in a callback that takes them as a parameter. Or you could return a Task<HashMap<String, Parking>> pretty similar to what Firebase does got get().

For an example of the callback, see my longer explanation on: getContactsFromFirebase() method return an empty list

How can I wait until Firebase Database data is retrieved in Flutter?

A listener is something that waits for changes (new documents added etc.) and notifies you whenever that happens. So it isn't something that starts/ends after you call it - you typically create it in the init of your Flutter class, and it changes state whenever something changes.

It looks like you want to grab all the users, once, and not listen like you're currently doing.

So instead of listening, perhaps just read the data. Something like:

// fetch all the documents
final allDocs =
await FirebaseFirestore.instance.collection('users').get();
// map them to something like your strings.
final thedetails = allDocs.docs.map((DocumentSnapshot e) => e.data()!.toString()).toList();
return thedetails;

How to wait for a Firebase retrieve value and only then exit the function?

Use async/await:

async function checkBuyingCondition(prefix) {
var res = '';

var currentPriceOpenRef = firebase.database()
.ref(`dailyT/currentPriceOpen/${nextDayTrading}`)
.orderByChild('prefix')
.equalTo(prefix);

var snapshot = await currentPriceOpenRef.once('value');

if(snapshot.exists()) {
snapshot.forEach(function(childSnapshot) {
var val = childSnapshot.val();
res = `${val.currentPriceOpen}`;
});
} else {
res = 'NA';
}

return res;
}

Take note that this does not make your function synchronous at all, thus the async keyword at the beginning of your function declaration; it just makes your function look like one.

On the 3rd line inside the function you'll notice the await keyword. This waits for your promise to resolve then returns the result which in your case, is the snapshot from Firebase. You can only use await inside async functions.

More Reading: Javascript Async/Await



Related Topics



Leave a reply



Submit