首页 > 解决方案 > 循环运行速度比 Firestore 查询任务快

问题描述

我们在“模块”集合中有 2 个文档,它们又分别有 5 个和 6 个文档,位于“模块”下的一个名为“课程”的集合中。当我们运行一个循环来解析集合“Modules”中的文档以使用 Firestore 从集合“Lessons”中获取文档时,外部 for 循环比 firestore 查询本身运行得更快,导致值在集合之间互换。我们尝试使用 Tasks.whenAllSuccess() 或 Tasks.whenAllComplete() 找到多种解决方案,但除了让主线程休眠 1 秒外,没有任何效果。在这种情况下,查询获取了适当的值。但是,让线程进入睡眠状态肯定会冻结应用程序,这是不可取的。下面附上代码片段:

 for (String moduleId : modulesDocumentIds)
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            firebaseFirestore.collection("Users")
                    .document(userDocumentId)
                    .collection("Courses")
                    .document(courseDocumentId)
                    .collection("Modules")
                    .document(moduleId)
                    .collection("Lessons")
                    .orderBy("lesson_number",Query.Direction.ASCENDING)
                    .get()
                    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<QuerySnapshot> task) {

                            for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult())
                            {

                                // Showing Lessons


                                             updateCourseCompletion();
                                                }
                                            });

                                        }
                                    }
                                }
                            }


                        }
                    });

在这里,如果 moduleDocumentIds 有 2 个 String 值,但没有让线程休眠,因为 for 循环比 Firestore Query 任务运行得快,所以为第二个 moduleId 字符串获取课程,然后为第一个 moduleId 字符串获取课程,导致价值交换。我们还不能为此找到解决方案。有人可以请教吗?

标签: javaandroidfirebasegoogle-cloud-firestore

解决方案


您可以为 firestore 查询创建一个函数,并在收到 for 循环项的响应后调用该函数。

private fun firebasecall() {
        var module = modulesDocumentIds.get(index)
//place your firestore call here
        firebaseFirestore.collection("Users")
            .document(userDocumentId)
            .collection("Courses")
            .document(courseDocumentId)
            .collection("Modules")
            .document(moduleId)
            .collection("Lessons")
            .orderBy("lesson_number",Query.Direction.ASCENDING)
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull (Task<QuerySnapshot>) task) {
                    index++
                    if (index < modulesDocumentIds.size) {
                        firebasecall()
                    } else {
                        //loop completes
                    }

                });

            }
    }

第一次调用方法:

if (modulesDocumentIds.size > 0) {
        firebasecall()
    }

希望它会有所帮助。


推荐阅读