Search code examples
androidfirebasefirebase-realtime-databasefirebaseui

FirebaseIndexRecyclerAdapter - How to get the value of each key from the key reference location?


I have the following denormalized data structure: A Contact can associate with multiple Records. A Record can have multiple associated Contacts (many<->many relationship). To keep track of their relationship, an int value to indicates the contact's role in a particular record, and store the role value in two separate references

Contact
- Contact1:data
- Contact2:data
- Contact3:data

Record
- Record1:data
- Record2:data

Record_Role_Ref
- Record1 
-- Contact1: roleA
-- Contact2: roleA
-- Contact3: roleD
- Record2
-- Contact1: roleB

Contact_Role_Ref
- Contact1
-- Record1: roleA
-- Record2: roleB

I'm using FirebaseIndexRecyclerAdapter is to show a list of associated Contacts to a particular Record id. So for the key reference I would use Record_Role_Ref/record_id, and for the data reference I would use Contact, like so:

// Setup the reference to the all the associated contact list in record_role_ref, using the record id as key
Query mRecordRoleRef = firebaseDatabase.getReference().child(DB_RECORD_ROLE_REF).child(mRecordId);

// Reference the Contact data ref
Query mContactRef = firebaseDatabase.getReference().child(DB_CONTACT);

FirebaseIndexRecyclerAdapter mContactAdapter = new FirebaseIndexRecyclerAdapter<Contact, ContactViewHolder>(Contact.class,
        R.layout.item_contact,
        ContactViewHolder.class,
        mRecordRoleRef, // The Firebase database location containing the keys associated contacts to this record
        mContactRef)// The Firebase database location to watch for data changes. Each key key found at keyRef's location represents a list item in the RecyclerView.

Limitation(s): I don't want to store the role value in each contact and record object because each time a role is changed, both the contact and record's entire object would have fetched and updated. Users want to delete, modify, move both contact and records, and change roles.

Problem(s): The contact's role value is stored as value of the key in the mRecordRoleRef. Is it possible/how to get the value from the key reference in on-go with FirebaseIndexRecyclerAdapter? What is the good/best practice in this kind of situation?

Thanks In Advance :)


Solution

  • As of now, I just form another data read request inside the populateViewHolder callback method. Since the data read request is itself also async, I'm not yet sure if this would work for a large list and when the view recycles. The viewHolder returned by the populateViewHolder is set to final.

    Query mRecordContactRoleRef = firebaseDatabase.getReference().child(DB_RECORD_CONTACT_ROLE_REF).child(mRecordId).child(mContact.getContactId());
    
    mRecordContactRoleRef.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            // Getting the role int base on record type
                            Long roleNum = (Long) dataSnapshot.getValue();
                            viewHolder.setContactRoleTv("hi, the role is " + roleNum);
                        }
    
                        @Override
                        public void onCancelled(DatabaseError databaseError) {
    
                        }
                    });