【问题标题】:How to get data from OnSuccessListener<QuerySnapshot>()如何从 OnSuccessListener<QuerySnapshot>() 获取数据
【发布时间】:2019-08-02 23:52:46
【问题描述】:
public class MainActivity extends AppCompatActivity {


    private static final String TAG = "100";
    FirebaseFirestore db;

    String checkCode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        db= FirebaseFirestore.getInstance();

        db.collection("Users")
                .whereEqualTo("level", "admin")
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        if (!queryDocumentSnapshots.isEmpty()) {
                            List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments();
                            for (DocumentSnapshot d : list) {
                                checkCode = (String) d.get("kode");
                                Toast.makeText(MainActivity.this, "From inside : "+checkCode, Toast.LENGTH_LONG).show();
                                }
                            }
                        }
                    });
        Toast.makeText(MainActivity.this, "From outside : "+checkCode, Toast.LENGTH_LONG).show();
    }
}

我仍然对如何从 Cloud Firestore 获取数据感到困惑。 所以我尝试制作一个简单的代码来从那里获取数据。我放了1111代码。

我运行程序后,里面的吐司给我:

From inside : 1111 

但是外面的吐司给了我:

From outside : null

这是为什么呢? 我该如何解决?

【问题讨论】:

标签: java android google-cloud-platform


【解决方案1】:

您正在对 Firestore 进行异步调用。 OnSuccessListeneronSuccess() 方法在检索数据时调用,在您显示 Toast 而 checkCode 仍然为空之后。您可以将 toast 移动到 onSuccess() 中,或者只使用 Log 打印到控制台。

【讨论】:

  • 我想保存值,而不是打印,Log能做到吗?
  • 保存是什么意思?如果你有一个函数a()需要checkCode运行,你可以在onSuccess()中为checkCode赋值后调用它。
  • 我明白了,但这是不可能的,你的逻辑应该从onSuccess() 继续。或者您可以切换到 MVP 或 MVVM 模式以获得更体面的结构。
  • @Mehmed 我现在专门为这些类型的问题做了一个答案,希望它在未来对其他人有所帮助:D stackoverflow.com/questions/57330766/…
  • @aldinugraha 您的 Firestore 调用是在另一个线程中完成的(因此不会阻塞 UI),当通过 onSuccess() 准备好响应时,结果会传递给 UI 线程(Android 中的主线程)。因此,您应该能够在onSuccess() 中操作您的视图。但是,如果您在 onSuccess 内部 setText() 但在调用 onSuccess() 之前尝试 getText(),您将无法正确获取文本,因为您在外部 Toast 上获得 null。
【解决方案2】:

答案很简单,你在全局范围内声明了checkCode 变量,它没有任何值。所以它将是null 值,这个值在那里烤。但是,虽然OnSuccessListener 执行它的值将由代码checkCode = (String) d.get("kode"); 分配,所以你得到1111 作为它的值。

【讨论】:

【解决方案3】:

onSuccess(QuerySnapshot queryDocumentSnapshots){} 中的代码是一个异步回调see this answer for an explanation,因为对 Firebase 的调用可能需要一些时间才能完成。 因此,Toast.makeText(MainActivity.this, "From outside : "+checkCode, Toast.LENGTH_LONG).show(); 行将始终在回调之前执行。

【讨论】:

【解决方案4】:

要将 QuerySnapshot 转换为对象列表,请使用:

querySnapshot.toObjects(YourObject.class)

在将值分配给 checkCode 之前触发 Tost FromOutside 行,因为对 firebase 的查询是异步的。这就是 FromOutside 为空的原因。

【讨论】:

猜你喜欢
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 2020-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
相关资源
最近更新 更多