在Android上从Firebase Firestore查询对象列表

时间:2018-08-22 10:35:48

标签: java android firebase google-cloud-firestore

我正在尝试一种方法来查询我的Cloud Firestore database中的项目列表。然后,我将使用上述列表设置一个RecyclerView适配器,它应该显示得很好。截至目前,RecyclerView为空。 (我还用虚拟项目测试了RecyclerView,它们显示得很好)

在我方法的最后,项目列表仍然为空。日志以奇怪的顺序显示(最后的日志显示在其他日志之前)。日志顺序使我怀疑侦听器中正在运行一些单独的线程。我不确定如何同步它们。

private List<Project> projects;
private FirebaseFirestore db;

...在 onCreateView()中(我正在处理片段):

 db = FirebaseFirestore.getInstance();
 queryAllProjects();
 recyclerView.setAdapter(new ProjectRecyclerViewAdapter(projects, ...

...

 private void queryAllProjects() {
        projects = new ArrayList<>(); 
        //I've already tried to make a local list and return that, however, 
        //the compiler would force me to declare the list as final here, and it wouldn't solve anything.
        db.collection("projects")
                .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());
                                Project project = document.toObject(Project.class);
                                projects.add(project);
                            }
                            Log.d(TAG, "After for loop: " + projects.toString()); 
                            //Here the list is OK. Filled with projects. 
                            //I'd like to save the state of the list from here
                        } else {
                            Log.d(TAG, "Error getting document: ", task.getException());
                            Toast.makeText(getContext(), R.string.error, Toast.LENGTH_SHORT).show();
                        }
                    }
                });
        Log.d(TAG, "End of method: " + projects.toString()); 
        //Oddly enough, this log displays before the other logs. 
        //Also, the list is empty here, which is probably what I'm unintentionally feeding into the Recycler View's adapter
    }

这是我一直关注的官方文档

  

https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects

2 个答案:

答案 0 :(得分:0)

projects.add(project);
adapter.notifyDataSetChange()

在列表添加后调用notifyDataSetChange()

答案 1 :(得分:0)

您现在不能使用尚未加载的内容。换句话说,您不能简单地将projects ArrayList设置为全局变量并在onComplete()方法之外使用它的值,因为由于该方法的异步行为,它将始终为null。这意味着在您尝试使用以下日志语句时:

Log.d(TAG, "End of method: " + projects.toString()); 

数据尚未从数据库中加载完毕,因此无法访问。

对此问题的快速解决方案是将这行代码移动到onComplete()方法中,否则,我建议您从 post 在其中,我解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。

还有另外一个 answer ,它显示了如何将列表移到回调之外。