[英]Firebase Query to fetch data from two nodes together
我在 Firebase 实时数据库中有一个名为“Posts”的根节点。 在里面,我有两个名为“ImagePosts”和“TextPosts”的节点。 在“ImagePosts”(和“TextPosts”)中,我有各种帖子的 postId。 在 postID 中,我拥有该特定帖子的所有详细信息,包括 postAt(发布时间)。
我想要做的是编写一个查询以从“ImagePosts”和“TextPosts”中获取数据并以降序/倒序显示所有帖子(即,最后/最近发布的帖子应显示在顶部在我的回收站视图中根据“postedAt”)。
为了实现这一点,我创建了一个名为 Post 的模型和两个名为“PostAdapter”和“TextPostAdapter”的适配器。 我的回收站视图是“DashboardRV”。 到目前为止我尝试了什么:
Home Fragment 代码:
public class HomeFragment extends Fragment {
ShimmerRecyclerView dashboardRV;
ArrayList<Post> postList;
public HomeFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
dashboardRV = view.findViewById(R.id.dashboardRv);
dashboardRV.showShimmerAdapter();
postList = new ArrayList<>();
PostAdapter postAdapter = new PostAdapter(postList, getContext());
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
dashboardRV.setLayoutManager(layoutManager);
dashboardRV.addItemDecoration(new DividerItemDecoration(dashboardRV.getContext(), DividerItemDecoration.VERTICAL));
dashboardRV.setNestedScrollingEnabled(false);
dashboardRV.setAdapter(postAdapter);
postList.clear();
database.getReference()
.child("Posts")
.child("ImagePosts")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Post post = dataSnapshot.getValue(Post.class);
post.setPostId(dataSnapshot.getKey());
postList.add(post);
}
Collections.reverse(postList);
dashboardRV.hideShimmerAdapter();
postAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
database.getReference()
.child("Posts")
.child("TextPosts")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
postList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Post post = dataSnapshot.getValue(Post.class);
post.setPostId(dataSnapshot.getKey());
postList.add(post);
}
Collections.reverse(postList);
dashboardRV.hideShimmerAdapter();
textPostAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
但是这种方法的问题在于它不会同时显示所有的“TextPosts”和“ImagePosts”。 它只显示打开应用程序上的所有图像帖子,然后当我更改片段并返回时,它会显示所有文本帖子。 我只是被困在这里。
一次只为一个回收者视图使用一个适配器:
这是具有(图像和文本帖子)的单个适配器的代码:
postList = new ArrayList<>();
PostAdapter postAdapter = new PostAdapter(postList, getContext());
dashboardRV.setAdapter(postAdapter);
// call clear before refreshing the list
postList.clear();
database.getReference()
.child("Posts")
.child("ImagePosts")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
Post post = dataSnapshot.getValue(Post.class);
post.setPostId(dataSnapshot.getKey());
postList.add(post);
}
Collections.sort(postList);
dashboardRV.hideShimmerAdapter();
postAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
database.getReference()
.child("Posts")
.child("TextPosts")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren())
Post post = dataSnapshot.getValue(Post.class);
post.setPostId(dataSnapshot.getKey());
postList.add(post);
}
Collections.sort(postList);
dashboardRV.hideShimmerAdapter();
postAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
// 使 Post 类实现与获取后对列表进行排序相当:
// A class 'Post' that implements Comparable
class Post implements Comparable<Post>
{
...
// Used to sort posts by their postedAt
public int compareTo(Post p)
{
return this.postedAt - p.postedAt;
}
...
}
此链接将有助于探索如何根据postedAt 进行排序:Using Comparable
要在本地合并 2 个单独的 Firebase 实时数据库请求,我建议您使用Tasks.whenAllSuccess()方法。 您可以使用以下代码行来实现这一点:
DatabaseReference imagePostsRef = database.getReference()
.child("Posts")
.child("ImagePosts");
DatabaseReference textPostsRef = database.getReference()
.child("Posts")
.child("TextPosts");
Task firstTask = imagePostsRef.get();
Task secondTask = textPostsRef.get();
Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
@Override
public void onSuccess(List<Object> list) {
//Do what you need to do with your list
}
});
如您所见,当覆盖“onSuccess()”方法时,结果是一个对象列表。 最后,只需将列表中的每个对象映射到 Post 类型的对象,并将新列表传递给单个适配器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.