首页 > 解决方案 > 有什么方法可以让我的应用在继续代码之前等待从 Firebase 检索数据?

问题描述

我的应用程序必须在 ListView 上显示名称列表。这些名称以下列方式存储在 Cloud Firestore 中:

集合:用户 - 文档:按用户 UID 组织 - 字段:名称(我必须注意每个用户还有其他字段,但是我需要专门检索名称字段)

为此,我有一个检索所有文档或用户 UID 的第一个列表。然后在 for 循环中使用第一个列表来检索 users 集合中每个用户的名称。

但是,由于 Firebase 异步检索数据,某些名称通常会丢失,并且最终会以杂乱无章的方式显示(与从第一个列表传递 uid 的顺序不一致)。

如果有人能给我任何关于如何让 Firebase 在继续 for 循环之前等待数据被检索的见解,我们将不胜感激!

下面是我的一些代码,可以让您更好地了解我在做什么。

代码的第一部分,成功检索所有文档(uid)并将它们放在列表中

subTopicsDatabase.collection("schoolTopics").document(docKey).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {

                    if (task.isSuccessful()){

            DocumentSnapshot document = task.getResult();

            if (document.exists()) {

                List<String> list = new ArrayList<>();

                Map<String, Object> map = document.getData();
                if (map != null) {
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        list.add(entry.getValue().toString());
                    }

                }

                }});

代码的第二部分,由于 Firebase 的异步行为而不起作用。


for (int i = 0; i<list.size(); i++) {

                        String uid = list.get(i);

                        Toast.makeText(TutorsListActivity.this, uid, Toast.LENGTH_LONG).show();

                        subTopicsDatabase.collection("users").document(uid).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                            @Override
                            public void onSuccess(DocumentSnapshot documentSnapshot) {

                                if (documentSnapshot.exists()) {

                                    String stName = documentSnapshot.getString("name");
                                    ArrayAdapter<String> adapter = new ArrayAdapter<>(TutorsListActivity.this, R.layout.item_subtopic, testList);
                                    adapter.notifyDataSetChanged();
                                    sListView2.setAdapter(adapter);

                                }

                                }

                            });
                        }

标签: javaandroidfirebasegoogle-cloud-firestore

解决方案


您断言由于 Firebase 的异步行为而无法正常工作是不正确的。您的视图未按您希望的方式显示的原因是您每次从 Firebase 收到文档时都在更新适配器。

在伪代码中,这是应该发生的:

// Create function with completion block - i.e. fetchTopicNames
//
// Create array to hold fetched String values - i.e. topicNames
// For loop to request each document
//    add String value to `topicNames`
//    if current iteration is last iteration, finish forLoop and return topicNames
//

在另一种方法中,调用您新创建的方法,使用您的完整列表更新您的适配器topicNames。然后您还可以对您Array喜欢的过滤和排序执行其他操作。可能还有一种更有效的方法,我只是为您提供完成任务的最基本方法。


推荐阅读