如何从Firebase Realtime Database获取子值并进行去重筛选?
问题解答
你编写的这段代码已经可以实现需求,逻辑完全通顺:
- 首先通过
orderByChild("country").equalTo()完成服务端过滤,只会拉取对应国家下的所有帖子数据,不会拉取其他国家的冗余数据 - 之后在遍历数据时判断sub是否已经存在于列表中,不存在才加入,天然完成了去重,最终得到的列表就是目标国家下所有存在对应帖子的sub值,且每个sub仅出现一次。
优化建议
如果后续数据量较大,可做两处优化提升运行效率:
- 用
HashSet代替ArrayList做去重判断:ArrayList的contains()方法时间复杂度为O(n),HashSet的contains()为O(1),查询效率更高,优化后的代码示例如下:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference postsRef = rootRef.child("Posts"); // 此处可替换为用户设置的国家变量 Query query = postsRef.orderByChild("country").equalTo(userSelectedCountry); query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() { @Override public void onComplete(@NonNull Task<DataSnapshot> task) { if (task.isSuccessful()) { Set<String> subSet = new HashSet<>(); for (DataSnapshot ds : task.getResult().getChildren()) { String sub = ds.child("sub").getValue(String.class); // HashSet会自动处理去重,无需手动判断是否存在 if(sub != null) { subSet.add(sub); } } // 按需转换为List结构传给RecyclerView Adapter即可 List<String> subList = new ArrayList<>(subSet); for (String sub : subList) { Log.d("TAG", sub); } } else { Log.d("TAG", task.getException().getMessage()); } } });
- 给
country字段加数据库索引,避免数据量大时查询变慢,只需在Firebase控制台的Realtime Database规则中添加如下配置:
{ "rules": { "Posts": { ".indexOn": "country" } } }
内容的提问来源于stack exchange,提问作者user16489264
相关产品推荐
相关产品推荐

