Firestore Oncompletelistener
Solution 1:
The data is loaded from Cloud Firestore asynchronously. By the time your return BanderaValidarCorreoDB
, the data hasn't loaded yet. There is no way to make the return statement wait for the data to be loaded. That is by design, and I highly recommend embracing programming against asynchronous APIs sooner rather than later.
The solution can be one of two things:
- Move the code that needs the data into
onComplete
. - Pass your own callback interface into your helper function that loads the data.
Moving the code that needs the data into onComplete
is the simplest. It's similar to how you already call setBanderaValidarCorreoDB
, but then also call the code that needs the value of BanderaValidarCorreoDB
:
publicvoidonComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshotdocument = task.getResult();
if (document.exists()) {
setBanderaValidarCorreoDB(true);
} else {
setBanderaValidarCorreoDB(false);
}
} else {
Toast.makeText(contextoRegistro, "ERROR al Realizar la validacion de Correo"+ task.getException(), Toast.LENGTH_SHORT).show();
setBanderaValidarCorreoDB(false);
}
doSomethingWithBanderaValidarCorreoDB(BanderaValidarCorreoDB);
}
This is simple, but reduces the reuse of you helper function a bit. So you can also define your own interface, and pass that into your helper function to call back. Code may be simpler to follow than words here, so:
publicinterfaceBanderaValidarCorreoDBCallback {
voidonCallback(boolean value);
}
voidgetBanderaValidarCorreoDB(BanderaValidarCorreoDBCallback callback)DocumentReferencedocRef= db.getDb().collection("Usuarios").document(Correo);
docRef.get().addOnCompleteListener(newOnCompleteListener<DocumentSnapshot>() {
@OverridepublicvoidonComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshotdocument= task.getResult();
if (document.exists()) {
setBanderaValidarCorreoDB(true);
return;
} else {
setBanderaValidarCorreoDB(false);
return;
}
} else {
Toast.makeText(contextoRegistro, "ERROR al Realizar la validacion de Correo"+ task.getException(), Toast.LENGTH_SHORT).show();
setBanderaValidarCorreoDB(false);
return;
}
callback(BanderaValidarCorreoDB);
}
});
}
And then you invoke it as:
getBanderaValidarCorreoDB(newBanderaValidarCorreoDBCallback() {
@OverridepublicvoidonCallback(boolean value) {
System.out.println("Loaded "+value)
}
});
This is an extremely common source of confusion for developers new to asynchronous programming. So I also recommend you check out some of these other sources:
- How to check a certain data already exists in firestore or not
- Setting Singleton property value in Firebase Listener (which also shows that waiting sometimes is possible, but not reliably on Android).
- getContactsFromFirebase() method return an empty list
- Android: Get a Pojo List from Firebase during the first initialization from the Service Class
- Doug's great blog post on asynchronous APIs.
While many of these are for the Firebase realtime database, the problem and solution are the same across all technologies.
Post a Comment for "Firestore Oncompletelistener"