Peter Peter - 3 months ago 32
Android Question

Coupling FirebaseRecyclerViewAdapter to a Boolean/String Map.Entry

I'm using the

FirebaseRecyclerViewAdapter
from the
com.firebaseui:firebase-ui:0.2.0
library in many locations of my app. My question is how to apply it in situations where the query argument returns a number of 'index' entry values (Map.Entry).

As indicated in the Firebase documentation (https://www.firebase.com/docs/android/guide/structuring-data.html), I'm using indexes to keep the data structure flat. This leads to a situation in which I need to bind these indexes to my ViewHolder. Within the populate view method, I'm using the key of the index to retrieve the data to fill the viewholder with.

I'm having trouble to create the adapter, not sure how to define 'modelClass' argument in case of a Boolean/String Map.Entry:

mAdapter = new FirebaseRecyclerViewAdapter<Map.Entry<String, Boolean>, ItemViewHolder>(???.class, R.layout.my_card, ItemViewHolder.class, getItemIndexQuery(mKey) ) {
...
}

Answer

Your value is a Boolean, not a Map. So your comment is correct: you will need to specify Boolean/Boolean.class for the value type. To be able to then look up the key, you will need to upgrade to FirebaseUI-Android 0.2.2. In that release we added a populateViewHolder(VH, T, int) overload that gets the position of the item as a parameter. With that, you can look up the key of the item.

Say this is your JSON structure:

{
  "items": {
    "pushid1": "Fri Jan 01 2016 16:40:54 GMT-0800 (PST)",
    "pushid2": "Fri Jan 01 2016 16:41:07 GMT-0800 (PST)",
    "pushid3": "Fri Jan 01 2016 16:41:25 GMT-0800 (PST)",
    "pushid4": "Fri Jan 01 2016 16:41:37 GMT-0800 (PST)",
    "pushid5": "Fri Jan 01 2016 16:42:04 GMT-0800 (PST)"
  },
  "index": {
    "pushid1": true,
    "pushid3": true,
    "pushid5": true
  }
}

So we store strings representing date/times and have an index to select a subset of these items.

We can now load the nodes from the index, then load the items that those nodes refer to and display them in the views with:

FirebaseRecyclerViewAdapter<Boolean, ItemViewHolder> adapter = 
    new FirebaseRecyclerViewAdapter<Boolean, ItemViewHolder>(
        Boolean.class, android.R.layout.two_line_list_item, ItemViewHolder.class, ref.child("index")){
    protected void populateViewHolder(final ItemViewHolder viewHolder, Boolean model, int position) {
        String key = this.getRef(position).getKey();
        ref.child("items").child(key).addListenerForSingleValueEvent(new ValueEventListener() {
            public void onDataChange(DataSnapshot dataSnapshot) {
                String date = dataSnapshot.getValue(String.class);
                ((TextView)viewHolder.itemView.findViewById(android.R.id.text1)).setText(date);
            }

            public void onCancelled(FirebaseError firebaseError) { }
        });
    }
};

The output on screen:

Android app showing three dates

For the full code, see Activity34559171 in this repo.

Comments