使用FireBase/FireStore在Java的内部函数中访问数据 [英] Accessing data within an inner function in Java with FireBase/FireStore

查看:43
本文介绍了使用FireBase/FireStore在Java的内部函数中访问数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Google的FireStore后端编写一个Android应用程序.从官方文档中获取火库集合中所有文档的代码如下:

I am coding an android app using Google's FireStore backend. The code to grab all the documents in a firestore collection is as follows, from the official documentation:

db.collection("cities")
    .get()
    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot document : task.getResult()) {
                    Log.d(TAG, document.getId() + " => " + document.getData());
                }
            } else {
                Log.d(TAG, "Error getting documents: ", task.getException());
            }
        }
    });

上面的代码输出到 Log.d(...)的地方,我想让我的程序添加 document.getData()调用的结果到内部类/方法外部可访问的 ArrayList .我不确定执行此操作的最佳方法是什么.尝试更改return的 onComplete 方法的返回类型会产生错误.在这种方法中是否有访问元素的标准方法?

Where the above code outputs to Log.d(...), I would like to have my program add the results of the document.getData() call to an ArrayList accessible outside the inner class/method. I'm not sure what is the best way to do this. Attempting to change the return the return type of the onComplete method yields errors. Is there a standard way of accessing elements in methods like this?

声明变量并尝试在类中进行变异也是不可能的,除非变量是最终变量,否则将使问题无济于事.

Declaring a variable and trying to mutate within the class also isn't possible, unless the variable is final, which defeats the point.

推荐答案

这是一个异步调用(它会启动后台进程来执行Firebase查询,完成后它将执行您的 onComplete 侦听器),因此您不能期望在进行数据库调用后立即拥有数据.例如,如果您的函数看起来像

That is an asynchronous call (it launches a background process to do the Firebase query, and once that is done it executes your onComplete listener), so you can't expect to have the data in hand immediately after making the database call. For example, if your function looks like

void getData() {
    final List<MyData> list = new ArrayList<>();

    db.collection("cities")
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Log.d(TAG, document.getId() + " => " + document.getData());
                        list.add(new MyData(document.getData()));
                    }
                } else {
                    Log.d(TAG, "Error getting documents: ", task.getException());
                }
            }
        });

    Log.d(TAG, "List size = " + list.size()); // will print 0
    // list will be empty here, the firebase call will take hundreds 
    // to thousands of milliseconds to complete
}

您需要对程序进行结构设计,以便它可以等待数据到达.您可以通过几种方法来执行此操作.一种方法是让 list 成为由 onComplete 侦听器填充的类成员(然后,您必须构造程序以处理随机输入的数据).

You need to structure your program so that it can wait for the data to arrive. There are a couple ways you could do this. One would be to have list be a class member that gets filled by the onComplete listener (then you have to structure the program to handle data coming in at random times).

另一种方法是拥有一个数据处理程序例程,该例程接受 ArrayList 并对其进行处理.获取所有数据后,可以从 onComplete 侦听器调用此方法.例如:

Another way would be to have a data handler routine that takes the ArrayList and does something with it. This method could be called from the onComplete listener once you've gotten all the data. For example:

void getData() {
    db.collection("cities")
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<MyData> list = new ArrayList<>();
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Log.d(TAG, document.getId() + " => " + document.getData());
                        list.add(new MyData(document.getData()));
                    }
                    processData(list);
                } else {
                    Log.d(TAG, "Error getting documents: ", task.getException());
                }
            }
        });
}

void processData(List<MyData> data) {
    // do stuff with the data, or make a copy, or otherwise share it
    // with the rest of your program
}

这篇关于使用FireBase/FireStore在Java的内部函数中访问数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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