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:
Starting to load data
After starting to load data
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
"Loadstylesheetunprivileged" Error When Trying to Use CSS Stylesheet with Javafx
Find Out If Class Name Contains Certain Text
Java_Home Is Set to an Invalid Directory:
How to Get String Array from Arrays.Xml File
How to Change Color of Hamburger Icon in Material Design Navigation Drawer
How to Get an Android User's Email Address
How to Programmatically Enable Gps in Android Cupcake
Androidruntime Error: Parcel: Unable to Marshal Value
How to Disable Sslv3 in Android for Httpsurlconnection
How to Convert Firebase Data to Java Object...
Bitmapfactory.Decodestream Returning Null When Options Are Set
Exposed Beyond App Through Clipdata.Item.Geturi
Convert Utc to Current Locale Time