RecyclerView 无法从 FirebaseFirestore 正确加载数据
RecyclerView not loading data correctly from FirebaseFirestore
我正在使用 Java 和 Firestore 在 Android Studio 上创建一个应用程序,它允许用户制作出版物并将它们显示在带有 RecyclerView 的 Fragment 上。用户创建一个配置文件(名称、头像),该配置文件保存在名为“Users”的 collection 中以用户 UID 命名的文档中。出版物被保存到另一个名为“Posts”的collection(标题、内容、图片、头像、名称)。
我写了两个查询,一个是从“Posts”collection 中获取 posts 的标题和内容,以及 UID,然后执行另一个查询从 poster 获取名称和图片,然后所有这些字段都进入“Post”object 并发送到填充 RecyclerView 的 ArrayList。
问题:posts 在 RecyclerView 上完美加载,但用户图片(我从另一个 collection 获得的图片)给我带来了很多问题。有时加载,有时不加载,有时只加载前 post 甚至前三个 post。我不明白可能出了什么问题。我正在 post 编写代码:
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();
}
}
});
}
如果要显示 post 详细信息,同时显示用户详细信息,则必须在第二次请求获取 name
和image
完成。所以你必须移动以下两行代码:
postList.add(post);
postAdapter.notifyDataSetChanged();
紧接着:
post.setAvatar(documentSnapshot.getString("image").toString());
除此之外,您还应该考虑使用另一个选项,称为 。这意味着您可以在 post 文档中添加用户的 name
和 image
。这样就不需要再进行第二次查询了,因为所有的数据都已经存在于post文档中了。如果您是 NoSQL 数据库的新手,这听起来可能有点奇怪,但我向您保证这是很常见的做法。
另请注意,两种解决方案都不比另一种好。根据您的应用程序中可能发生的更改数量,关于名称和用户图像的更新,您必须检查哪种解决方案更适合您的项目。
您还可以查看以下内容post,以更好地了解 Firebase 的异步特性API:
我正在使用 Java 和 Firestore 在 Android Studio 上创建一个应用程序,它允许用户制作出版物并将它们显示在带有 RecyclerView 的 Fragment 上。用户创建一个配置文件(名称、头像),该配置文件保存在名为“Users”的 collection 中以用户 UID 命名的文档中。出版物被保存到另一个名为“Posts”的collection(标题、内容、图片、头像、名称)。
我写了两个查询,一个是从“Posts”collection 中获取 posts 的标题和内容,以及 UID,然后执行另一个查询从 poster 获取名称和图片,然后所有这些字段都进入“Post”object 并发送到填充 RecyclerView 的 ArrayList。
问题:posts 在 RecyclerView 上完美加载,但用户图片(我从另一个 collection 获得的图片)给我带来了很多问题。有时加载,有时不加载,有时只加载前 post 甚至前三个 post。我不明白可能出了什么问题。我正在 post 编写代码:
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();
}
}
});
}
如果要显示 post 详细信息,同时显示用户详细信息,则必须在第二次请求获取 name
和image
完成。所以你必须移动以下两行代码:
postList.add(post);
postAdapter.notifyDataSetChanged();
紧接着:
post.setAvatar(documentSnapshot.getString("image").toString());
除此之外,您还应该考虑使用另一个选项,称为 name
和 image
。这样就不需要再进行第二次查询了,因为所有的数据都已经存在于post文档中了。如果您是 NoSQL 数据库的新手,这听起来可能有点奇怪,但我向您保证这是很常见的做法。
另请注意,两种解决方案都不比另一种好。根据您的应用程序中可能发生的更改数量,关于名称和用户图像的更新,您必须检查哪种解决方案更适合您的项目。
您还可以查看以下内容post,以更好地了解 Firebase 的异步特性API: