1

My Firebase Realtime Database is like this :

{Singer :
    Billie Eilish :
        01 :
            songType : "type01"
            songName : "bad guy"
        02 :
            songType : "type02"
            songName : "bury a friend"
    Lauv :
        01 :
            songType : "type01"
            songName : "I Like Me Better"
        02 :
            songType : "type03"
            songName : "lonely"
    Anne Marie :
        01 :
            songType : "type02"
            songName : "2002"
        ...
        ...
        ...
}

If I want to get all the song that "type01", what should I do? This is my Adapter class that show the data in recyclerView in MainActivity.

Adapter class :

public class MyAdapter extends Recycler.Adapter {
    ...
    @Override
    public void onBindViewHolder(@Nonnull ViewHolder holder, int i) {
        ...
        Query query = FirebaseDatabase.getInstance().getReference().child("Singer");
        options = new FirebaseRecyclerOptions.Builder<ItemModel>().setQuery(query, new SnapshotParser<ItemModel>() {
            @NonNull
            @Override
            public ItemModel parseSnapshot(@NonNull DataSnapshot snapshot) {
                if (snapshot.child("songType").getValue().toString().equals("type01") {
                    String song = snapshot.child("songName").getValue().toString();
                    return new ItemModel(song);
                }
                return null;
            }
        }).build();
        recyclerAdapter = new AnotherAdapter(options);
        recyclerAdapter.startListening();
}

I think it is weird in the query. It called only the child "Singer". I want to call all the child and get what songType is "type01". AnotherAdapter is just extending FirebaseReyclcerAdapter and just set the text in its AnotherViewHolder.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
H.JiMan
  • 269
  • 1
  • 2
  • 10

2 Answers2

3

why don't you just go with fetch data which contains only songType : type01 try this

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();

Query query = reference.child("Singer").orderByChild("songType").equalTo("type01");
query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()) {
            for (DataSnapshot issue : dataSnapshot.getChildren()) {
                //set featched value to recyclerview 
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});
Ashish
  • 6,791
  • 3
  • 26
  • 48
Black mamba
  • 462
  • 4
  • 15
  • Thank you for your help. But there is a little problem... Your code [reference.child("SInger").orderByChild("songType").equalTo("type01")] can't read the data... Maybe each singer data has the number of sing list like 01, 02, 03 ... – H.JiMan Sep 25 '19 at 01:26
2

Since you're passing a reference to Singers into the recycler view, your parseSnapshot is called for each singer. In there you need to make sure you check the songType of each song child of the singer, where now you check the songType of the singers themselves (which never exists, so never goes into the if block).

So it'd be something like this:

Query query = FirebaseDatabase.getInstance().getReference().child("Singer");
options = new FirebaseRecyclerOptions.Builder<ItemModel>().setQuery(query, new SnapshotParser<ItemModel>() {
    @NonNull
    @Override
    public ItemModel parseSnapshot(@NonNull DataSnapshot snapshot) {
        String song = "No song found";
        for (DataSnapshot songSnapshot: snapshot.getChildren()) {
            String songType = songSnapshot.child("songType").getValue(String.class)
            if (songType.equals("type01") {
              song = songType;
              ...

I'm not sure though if this is what you want, because you seem to want a list of songs, while you're passing in a list of singers. The above will only work if each singer has exactly one song of type01 (not 0, not more).

If that is not the case, the adapters in FirebaseUI won't fit your needs with your current data structure, since they show a list of items from the database, while you want to show items from a tree-like structure.

The two main options that come to mind in that case:

  1. Build your own adapter, typically based on ArrayAdapter as shown here.
  2. Change your data structure so that all songs are in a flat list (and the singer then becomes a property of each song).
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you for help! Um... Can I ask question?? What is the role ```isType``` boolean?? – H.JiMan Sep 25 '19 at 03:42
  • I cleaned up that code a bit. But seriously consider using a data structure that matches the needs of your UI. Since you want to show a list of artists with their type01 song, store in your database a list of artists with **just** their type01 song title. – Frank van Puffelen Sep 25 '19 at 05:15