我想看看该代码在执行程序中有什么错误,当我对其进行编译时,它只返回log 1,3,2的值,而我希望log 2早于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
答案 0 :(得分:0)
数据是从Cloud Firestore异步加载的。到您的return BanderaValidarCorreoDB
时,数据尚未加载。无法使return语句等待数据加载。那是设计使然,我强烈建议尽早采用异步API进行编程。
解决方案可以是以下两件事之一:
onComplete
。将需要数据的代码移至onComplete
是最简单的。这与您已经调用setBanderaValidarCorreoDB
的方式类似,但同时又调用需要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);
}
这很简单,但是会稍微减少辅助功能的重用。因此,您还可以定义自己的接口,并将其传递给您的帮助器函数以进行回调。代码可能比这里的文字更易于理解,因此:
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)
}
});
对于刚接触异步编程的开发人员来说,这是一个非常常见的困惑源。因此,我还建议您检查其他一些来源:
尽管其中许多用于Firebase实时数据库,但所有技术中的问题和解决方案都是相同的。