java - 使用 FireBase/FireStore 访问 Java 内部函数中的数据

标签 java android firebase google-cloud-firestore

我正在使用 Google 的 FireStore 后端编写 Android 应用程序。抓取firestore集合中所有文档的代码如下,来自官方文档:

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。我不确定执行此操作的最佳方法是什么。尝试更改 onComplete 方法的返回值类型会产生错误。是否有一种标准的方法来访问这样的方法中的元素?

声明一个变量并尝试在类中进行变异也是不可能的,除非该变量是最终的,这违背了要点。

最佳答案

这是一个异步调用(它启动一个后台进程来执行 Firebase 查询,一旦完成,它就会执行您的 onComplete 监听器),因此您不能期望在执行以下操作后立即获得数据数据库调用。例如,如果您的函数看起来像

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填满的类(class)成员监听器(然后您必须构建程序来处理随机传入的数据)。

另一种方法是使用一个数据处理程序例程,该例程采用 ArrayList并用它做一些事情。该方法可以从 onComplete 调用获得所有数据后,监听器。例如:

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
}

关于java - 使用 FireBase/FireStore 访问 Java 内部函数中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53056139/

相关文章:

java - 如何调用Akka helloworld?

android - sp在ldpi,mdpi,hdpi,xhdpi,xxhdpi中自动互相转换

android - 结合使用ProgressDialog和线程时,应用程序因方向更改而崩溃

android setBackgroundColor 在运行时和其他一般混淆有帮助吗?

android - 如何按升序或降序排列firebase数据库数据?

java - 字符串匹配和整数匹配的时间复杂度

java - Intellij IDEA 项目 View 不像以前那样显示结构。

javascript - Redux Thunk函数后的回调: Uncaught TypeError: Cannot read property 'then' of undefined

java - firestore 快照监听器的生命周期和定价之间有什么关系?

java - 设置java环境变量时是否必须仅指定JAVA_HOME作为变量名?