Reputation:
How can get the child values and filter from firebase realtime database?
Below is my architecture:
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
I want to read the value of sub, but there are a total of three values like DC, but I only want to fetch it once, because what I want to achieve is that states with a value will be displayed in the RecyclerView, but like AL, AZ, AL, AR and so on, it hasn't been added yet, so it won't be displayed.
So how can I do it?
I will use this methods to get post country, so how can show the subs and filter?
if the user set his country is USA then it's just show USA sub. If the user set country is EU then just set UK, FRA etc.
Only sub just wanna show once.
this is code.
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) {
}
});
And if I used this code, it's can realize, but cannot filter country
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!
}
}
});
how can merge it?
is like this ??
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!
}
}
});
Upvotes: 3
Views: 1390
Reputation: 600006
There is no reason why you can't filter on country in the second example. It should be a matter of:
DatabaseReference postsRef = rootRef.child("Posts");
Query query = postRef.orderByChild("country").equalTo("USA");
query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
...
The rest of your code can remain the same, and will loop over all posts from/about the USA and determine the unique sub
values in there.
The new error message that you provided in the comments says:
Index not defined, add ".indexOn": "country", for path "/Posts", to the rules
So to allow the query to run on the server, you'll need to add ".indexOn": "country"
to /Posts
in your databases's rules:
{
"rules": {
...
"Posts": {
".indexOn": "country"
}
}
}
Upvotes: 1