java - Firebase Query 从两个节点一起获取数据
问题描述
我在 Firebase 实时数据库中有一个名为“Posts”的根节点。在其中,我有两个节点,分别称为“ImagePosts”和“TextPosts”。在“ImagePosts”(和“TextPosts”)中,我有各种帖子的 postId。在 postID 中,我拥有该特定帖子的所有详细信息,包括 postedAt(发布时间)。
我想要做的是编写一个查询以从“ImagePosts”和“TextPosts”中获取数据,并以降序/反向顺序显示所有帖子(也就是说,最后/最近发布的帖子应该显示在顶部根据“postedAt”在我的回收站视图中)。
为此,我创建了一个名为 Post 的模型和两个名为“PostAdapter”和“TextPostAdapter”的适配器。我的回收站视图是“DashboardRV”。到目前为止我尝试了什么:
家庭片段代码:
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”。它只显示打开应用程序上的所有图像帖子,然后当我更改片段并返回时,它会显示所有文本帖子。我只是被困在这里。
解决方案
要在本地合并 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 类型的对象,然后将新列表传递给单个适配器。
推荐阅读
- php - 我在 init.php 文件中定义了一个变量(VOTING_ALLOWED),但我没有在其他页面中获得值
- sql-server - 如何在 SQL Server 扩展事件中单独跟踪游标语句?
- python-3.x - PyCharm Git VCS Grays Out 添加选项
- html - 制作简单的汉堡菜单
- mysql - 为什么我们对 MySQL 和 PostgreSQL 没有不同的文件扩展名?
- r - 重命名包含空格的数据框列名称
- swift - Google Admobs Xcode 警告
- powershell - 使用自定义函数从调用命令进行日志记录
- python - Python,硒每次在不同的浏览器窗口上打开我的网址
- html - 如何将代码中的数据库数据更改为其他内容?