繁体   English   中英

RecyclerView 无法从 FirebaseFirestore 正确加载数据

[英]RecyclerView not loading data correctly from FirebaseFirestore

我正在使用 Java 和 Firestore 在 Android Studio 上创建一个应用程序,该应用程序允许用户发布并在带有 RecyclerView 的 Fragment 上显示它们。 用户创建一个配置文件(名称、头像),该配置文件保存在名为“Users”的集合中以用户 UID 命名的文档中。 出版物被保存到另一个名为“帖子”(标题、内容、图片、头像、名称)的集合中。

我写了两个查询,一个从“帖子”集合中的帖子中获取标题和内容,以及 UID,然后执行另一个查询,从海报中获取名称和图片,然后所有这些字段都去在“Post”对象内并发送到填充 RecyclerView 的 ArrayList。

问题:帖子在 RecyclerView 上完美加载,但用户图片(我从不同集合中获取的图片)给我带来了很多问题。 有时它会加载,有时它不会加载,有时它只加载第一个帖子甚至前三个帖子。 我不明白可能出了什么问题。 我正在发布代码:

private void loadPosts() {
        Query postQuery = collectionReferencePosts.orderBy("timestamp", Query.Direction.DESCENDING);
        postQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                for (QueryDocumentSnapshot document : task.getResult()) {
                    Post post = new Post();
                    post.setTitle(document.getString("title"));
                    post.setContent(document.getString("content"));
                    post.setImage(document.getString("image"));
                    String posterUid = document.getString("useruid");
                    DocumentReference docRef = collectionReferenceUsers.document(posterUid);
                    docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                        @Override
                        public void onSuccess(DocumentSnapshot documentSnapshot) {
                            post.setName(documentSnapshot.getString("name").toString());
                            post.setAvatar(documentSnapshot.getString("image").toString());
                        }
                    });
                    postList.add(post);
                    postAdapter.notifyDataSetChanged();
                }
            }
        });
    }

如果要同时显示帖子详细信息以及用户详细信息,则必须在第二次获取nameimage的请求完成时通知适配器有关更改。 所以你必须移动以下两行代码:

postList.add(post);
postAdapter.notifyDataSetChanged();

紧接着:

post.setAvatar(documentSnapshot.getString("image").toString());

除此之外,您还应该考虑使用另一个选项,称为denomalization 这意味着您可以在发布文档中添加用户的nameimage 这样,就不需要执行第二次查询了,因为所有的数据都已经存在于 post 文档中了。 如果您是 NoSQL 数据库的新手,这听起来可能有些奇怪,但我向您保证这是很常见的做法。

另请注意,这两种解决方案都不比另一种更好。 根据您的应用程序中可能发生的更改数量,关于名称和用户图像的更新,您必须检查哪种解决方案更适合在您的项目中使用。

您还可以查看以下帖子,以更好地了解 Firebase API 的异步特性:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM