Firestore OncompleteListener

时间:2018-07-08 17:55:07

标签: android collections listener google-cloud-firestore document

我想看看该代码在执行程序中有什么错误,当我对其进行编译时,它只返回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

1 个答案:

答案 0 :(得分:0)

数据是从Cloud Firestore异步加载的。到您的return BanderaValidarCorreoDB时,数据尚未加载。无法使return语句等待数据加载。那是设计使然,我强烈建议尽早采用异步API进行编程。

解决方案可以是以下两件事之一:

  1. 将需要数据的代码移至 onComplete
  2. 将您自己的回调接口传递给加载数据的帮助器函数。

将需要数据的代码移至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实时数据库,但所有技术中的问题和解决方案都是相同的。