Following is the schema of my Firebase Realtime Database:
Chats node
- chats
- chatId
- chatId
- adminUserId
- chatSubject
- chatIconUrl
- chatCretionDate
- lastUpdated
- chatId
User chats node
- user_chats
- userId
- chatId: true
- userId
What I want to do:
What I want to do is to present a list of all chats a user is subscribed to in the ChatListFragment of my app and observe it for changes, e.g., new chat added, any chat removed, a change in chatSubject, chatIconUrl, lastUpdated etc.
What I have done:
Since I've already denormalized the data, the first step would be to retrieve a list of chat ids a given user is subscribed to, and this I can very easily achieve as follows:
FirebaseDatabase.getInstance().getReference("user_chats").child(userId).addValueEventListener()
Next task is to get the complete chat data from chats node against each of the chat ids retrieved above.
I know that I can't write a query to achieve this because the retrieved chat ids are a random subset out of the hundreds or thousands of total chat ids.
So, I loop through the retrieved chat ids and fire a query for each as follows and collect the retrieved Chat (A POJO that maps to the fields in chats node) object one by one in an ArrayList:
FirebaseDatabase.getInstance().getReference("chats").child(chatId).addValueEventListener()
Here, I've to ensure completeness of data by matching the size of ArrayList<Chat> with the size of chat ids retrieved from user_chats node. When both sizes are equal, I supply the ArrayList<Chat> to the ListAdapter.
BUT, in addition to above, I also have to deal with the following:
- See why onDataChanged() of the listener attached to each chat id has been called: to supply a new chat snapshot or report changes in an already supplied chat snapshot.
- Remove listener associated with a chat id that the given user is no longer subscribed to.
This becomes even more complicated when I try to do it all in a ViewModel using LiveData.
Here are my questions:
Do I really have to go through such a trouble just to compile a list of chats that a user is subscribed to? This is supposed to be the first screen of my app and I can't happen to get past it.
Is there a standard / better way to achieve my objective with the same data structure?
Do I need to make further changes in my data structure to achieve my objective? What I'm thinking is to expand the
user_chatsnode by adding the same fields thatchatsnode has. That seems pretty weird though because, first, if there are lets say, 500 members in a chat, there would be 500 ditto copies of the chat inuser_chatsnode and second, in case of any update in data, I would be updating the chat info inchatsnode and then all the 500 copies inuser_chatsnode. That would be ridiculous when we think about how frequently thelastUpdatedfield would be updated.
Any help would be really appreciated!