Firestore OncompleteListener [英] Firestore OncompleteListener
问题描述
我想看看该代码在执行程序中有什么错误,当我对其进行编译时,它只返回log 1,3,2的值,而我希望log 2早于3.
I want to see what is the error in this code for the executiom, when i compile it it just returns the values of log 1,3,2 , and i wanto log 2 to be before the 3
Log.d("1", "antes de validar");
DocumentReference docRef = db.getDb().collection("Usuarios").document(Correo);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
Log.d("2", "validar");
if (task.isSuccessful()) {
DocumentSnapshot document = 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;
}
}
});
Log.d("3", "despues de validar");
return BanderaValidarCorreoDB;
}
这是它的显示方式
07-08 13:47:56.968 6027-6027/felipe.monumentosfinalcertamen D/1: antes de
validar
07-08 13:47:56.980 6027-6027/felipe.monumentosfinalcertamen D/3: despues de validar
07-08 13:47:57.071 6027-6052/felipe.monumentosfinalcertamen W/EGL_emulation: eglSurfaceAttrib not implemented
07-08 13:47:57.071 6027-6052/felipe.monumentosfinalcertamen W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe2b2a700, error=EGL_SUCCESS
07-08 13:47:57.149 6027-6052/felipe.monumentosfinalcertamen W/EGL_emulation: eglSurfaceAttrib not implemented
07-08 13:47:57.149 6027-6052/felipe.monumentosfinalcertamen W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe2cf7540, error=EGL_SUCCESS
07-08 13:47:57.177 6027-6052/felipe.monumentosfinalcertamen V/RenderScript: 0xeff9b600 Launching thread(s), CPUs 4
07-08 13:47:58.483 6027-6027/felipe.monumentosfinalcertamen D/2: validar
07-08 13:52:35.654 6027-6068/felipe.monumentosfinalcertamen I/FirebaseAuth: [FirebaseAuth:] Loading module via FirebaseOptions.
[FirebaseAuth:] Preparing to create service connection to gms implementation
推荐答案
数据是从Cloud Firestore异步加载的.在您的返回BanderaValidarCorreoDB
时,数据尚未加载.无法使return语句等待数据加载.那是设计使然,我强烈建议尽早采用异步API进行编程.
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:
- 将需要数据的代码移到 onComplete .
- 将您自己的回调接口传递给加载数据的帮助器函数.
将需要数据的代码移到 onComplete
中是最简单的.类似于您已经调用 setBanderaValidarCorreoDB
的方式,然后又调用需要 BanderaValidarCorreoDB
值的代码:
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
:
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = 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:
public interface BanderaValidarCorreoDBCallback {
void onCallback(boolean value);
}
void getBanderaValidarCorreoDB(BanderaValidarCorreoDBCallback callback)
DocumentReference docRef = db.getDb().collection("Usuarios").document(Correo);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = 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);
}
});
}
然后您将其调用为:
getBanderaValidarCorreoDB(new BanderaValidarCorreoDBCallback() {
@Override
public void onCallback(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:
- 如何检查Firestore中是否已经存在某些数据
- 在Firebase Listener中设置Singleton属性值(这也表明有时可以等待,但在Android上无法可靠地等待).
- getContactsFromFirebase()方法返回空列表
- Android:在服务类的首次初始化过程中,从Firebase获取Pojo列表
- 道格很棒的博客文章发布于异步API .
- 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.
尽管其中许多用于Firebase实时数据库,但所有技术中的问题和解决方案都是相同的.
While many of these are for the Firebase realtime database, the problem and solution are the same across all technologies.
这篇关于Firestore OncompleteListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!