user16489264
user16489264

Reputation:

How can get the child values and filter from firebase realtime database?

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

Answers (1)

Frank van Puffelen
Frank van Puffelen

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

Related Questions