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 to wait for the data to be fetched from Firebase Database
To solve this problem, please add the declaration of your receiverNames
ArrayList inside the onDataChange()
method, otherwise it will be null. This is happening due to asynchronous behaviour of that method. If you want to use those values outside that method, please see my answer from this post.
How to wait for firebase data fetch finishes and get values not a promise in react-native?
When you are attempting to get your firebase response you're not actually waiting for it. The code below does not wait for it to be executed.
getCustomersOnQeueu = async () => {
let customers = this.customersRef.orderByChild("ticket").once('value')
return customers
}
To WAIT for it to be executed use AWAIT:
getCustomersOnQeueu = async () => {
let customers = await this.customersRef.orderByChild("ticket").once('value')
return customers
}
Handle data returned by an Async task (Firebase)
What you are looking for is Callback interface, as for your needs you need simple interface that implement single method with single parameter, as there is no out of the box convention for Java 6 (Android Java version) you can easily create it by yourself:
interface Callback {
void act(List<AttendModel> models);
}
pass it as an argument to the firebase wrapping method, and call it with the result.
public void getAllAttendeesFor(String UUID, final ArrayList<AttendModel> attendArray, final Callback callback) {
final DatabaseReference attendObjects = getDatabaseTableWith(Constants.tableAttendObject);
Query queryRef = attendObjects.orderByChild(Constants.taAttendObjectUUID).equalTo(UUID);
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
HashMap<String, Object> attend = (HashMap<String, Object>) postSnapshot.getValue();
String UUID = (String) attend.get(Constants.AttendObjectUUID);
String userUsername = (String) attend.get(Constants.AttendObjectUserUsername);
AttendModel attendModel = new AttendModel(userUsername, UUID);
attendArray.add(attendModel);
callback.act(attendArray)
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
then in your upper level method:
public void getAttendants() {
ArrayList<AttendModel> attendees = new ArrayList<AttendModel>();
FirebaseConnection.getInstance().getAllAttendeesFor(uuid, attendees,
new Callable<List<AttendModel) {
void act(List<AttendModel> attendees){
//here you can update the UI
Log.d("attendees", String.valueOf(attendees.size()));
}
};
}
Just be aware that you can update the UI only if onDataChange method of the firebase query is called on the main thread.
Retrieve data synchronously from firestore database
Consider a scenario.
There is an 'n' no. of collections in your database root and you have their names in a list. You have to get the size()
(No. of documents in it) of each of the collections. The only way to get this by synchronous calls is to wait until the pending request has been completed. You can achieve it like this:
private void syncDocumentCounts() {
if (position > names.size() - 1) {
adapter.notifyDataSetChanged();
} else {
FirebaseFirestore.getInstance().collection(names.get(position)).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
list.add(queryDocumentSnapshots.size());
position++;
syncDocumentCounts();
}
});
}
}
Here,
position
= public int = 0
names
= list of names of collections
list
is the list in which we have to add the value.
Related Topics
Playing an Arbitrary Tone With Android
Animate Change of View Background Color on Android
Android.View.Inflateexception: Binary Xml File Line #12: Error Inflating Class ≪Unknown≫
How to Get Pixel Color in Android
How to Send String from One Activity to Another
CSS Media Query - Soft-Keyboard Breaks CSS Orientation Rules - Alternative Solution
How to Pass Arraylist<Customeobject> from One Activity to Another
Accessing Localhost:Port from Android Emulator
Eclipse Error: R Cannot Be Resolved to a Variable
How to Draw Interactive Polyline on Route Google Maps V2 Android
Show Image View from File Path
How to Add a Border to the Top and Bottom of an Android View
How to Change Font Face of Webview in Android
Android - Sms Broadcast Receiver
How to Get Current Time from Internet in Android
Disable Scrolling in All Mobile Devices
How to Connect to More Than One Firebase Database from an Android App