如何从 firebase 实时数据库中获取子值和过滤器?
Posted
技术标签:
【中文标题】如何从 firebase 实时数据库中获取子值和过滤器?【英文标题】:How can get the child values and filter from firebase realtime database? 【发布时间】:2021-11-11 01:22:16 【问题描述】:下面是我的架构:
Posts
|--firebase key
|--title: test1
|--sub: NY
|--country: USA
--firebase key
|--title: test2
|--sub: DC
|--country: USA
--firebase key
|--title: test3
|--sub: DC
|--country: USA
--firebase key
|--title: test4
|--sub: FRA
|--country: EU
--firebase key
|--title: test5
|--sub: UK
|--country: EU
我想读取sub的值,但是像DC一样一共有三个值,但是我只想取一次,因为我想要实现的是有值的状态会显示在RecyclerView中,但是像AL、AZ、AL、AR等,还没有添加,所以不会显示。
那我该怎么做呢?
我会用这个方法来获取post country,那么如何显示subs和filter呢?
如果用户设置他的国家是美国那么它只是显示美国子。如果用户设置的国家是欧盟,那么只需设置英国、FRA 等。
只有 sub 只想显示一次。
这是代码。
DatabaseReference countryRef = FirebaseDatabase.getInstance().getReference("Posts");
Query query = countryRef.orderByChild("country").equalTo(country);
query.addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
@Override
public void onCancelled(@NonNull DatabaseError error)
);
如果我使用这个代码,它可以实现,但不能过滤国家
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference postsRef = rootRef.child("Posts");
postsRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>()
@Override
public void onComplete(@NonNull Task<DataSnapshot> task)
if (task.isSuccessful())
List<String> posts = new ArrayList<>();
for (DataSnapshot ds : task.getResult().getChildren())
String sub = ds.child("sub").getValue(String.class);
if(!posts.contains(sub))
posts.add(sub);
for (String post : posts)
Log.d("TAG", post);
else
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
);
如何合并?
是这样的吗??
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference postsRef = rootRef.child("Posts");
Query query = postsRef.orderByChild("country").equalTo("Australia");
query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>()
@Override
public void onComplete(@NonNull Task<DataSnapshot> task)
if (task.isSuccessful())
List<String> posts = new ArrayList<>();
for (DataSnapshot ds : task.getResult().getChildren())
String sub = ds.child("sub").getValue(String.class);
if(!posts.contains(sub))
posts.add(sub);
for (String post : posts)
Log.d("TAG", post);
else
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
);
【问题讨论】:
【参考方案1】:在第二个示例中,您没有理由不能过滤 国家/地区。应该是这样的:
DatabaseReference postsRef = rootRef.child("Posts");
Query query = postRef.orderByChild("country").equalTo("USA");
query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>()
...
您的代码的其余部分可以保持不变,并将遍历来自/关于美国的所有帖子,并确定其中唯一的 sub
值。
您在 cmets 中提供的新错误消息说:
索引未定义,添加 ".indexOn": "country", for path "/Posts", 到规则中
因此,要让查询在服务器上运行,您需要在数据库规则中将 ".indexOn": "country"
添加到 /Posts
:
"rules":
...
"Posts":
".indexOn": "country"
【讨论】:
它无法工作,总是加载...... 这似乎出乎意料。如果您在onComplete
中放置一个断点并在调试器中运行,它会被调用吗?如果有,if (task.isSuccessful())
是什么?
所以,不要使用 if (task.isSuccessful()) ??我会远程这个,我得到这个错误。 com.google.android.gms.tasks.RuntimeExecutionException: java.lang.Exception: 索引未定义,添加 ".indexOn": "country", for path "/Posts", 到规则
你能检查一下上下文吗?我会穿上我的代码
更新了我的答案以显示这一点,但我真的建议搜索您收到的错误消息:google.com/…以上是关于如何从 firebase 实时数据库中获取子值和过滤器?的主要内容,如果未能解决你的问题,请参考以下文章
从 Firebase 查询具有在 ArrayList 中找到的子值的对象