Firestore OncompleteListener [英] Firestore OncompleteListener

查看:104
本文介绍了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:

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

将需要数据的代码移到 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:

  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆