Reputation: 3637
I'm having hard time figuring out how to structure multi users chat room FirebaseDatabase
architecture properly.
Basically, the app supports private messages between users (could be between 2 users or multiple users). If it was between 2 users only, the data structure is quite easy really.
I'm trying to reduce the cost (I don't want when the current logged user is having a chat with someone and the observer is getting all the messages that are no related to this particular chat) and structure the data properly. If it was between 2 users only, I could always add the recepient under the current user ID and query only that node. But with multiple users (not even sure how many of them) I need to rely on a chat room Id but I'm having hard time with that.
So, here's the idea, let's say the user selects another to start a chat with. I was thinking about something like this:
The problem that I'm facing with this is maintaining that chatId
. Every time the user is about to send a new message, how do I check if there's already a chat with the same recepient (or recepients) based on the chatId
. This is the confusing part for me. I'm stuck on this for days now and I can't figure out a proper way to maintain that chatId
and query it properly. Any help is welcome.
Upvotes: 1
Views: 3886
Reputation: 35648
If I understand the question, the app has multiple users and those users could have chats 1-1 or 1-many and you want to avoid users getting events for chats they are not part of.
Let's start with a users node
users
uid_0
name: "Bill"
chats:
chat_id_0: true
chat_id_9: true
uid_1
name: "Jesse"
chats:
chat_id_0: true
chat_id_6: true
.
.
.
and then a simplified chats node
chats
chat_id_0:
uid_0: "Hey there, Jesse"
uid_1: "Sup Bill?"
chat_id_6:
uid_0: "This is Bill, anyone around?"
chat_id_9:
uid_1: "Look ma, no hands"
uid_7: "Impressive"
In the above, chat_id_x is created with .childByAutoId when the user starts a chat.
When Bill logs in (uid_0) read in his chats node and then add observers to the chats listed within that node. In this case, Bill is part of chat_id_0 and chat_id_9. Do the same process for Jesse who is part of 0 and 6.
Both Bill and Jesse are having a chat in chat_id_0, Bill is awaiting a reply from any users also watching chat_id_6 and Jesse is conversing with uid_7 in chat_id_9.
From there any time there's an event (.childAdded when a new message is added to a chat for example) only those users observing that chat ('subscribed') will receive an event.
Obviously more detail would be included in each chat node (timestamp etc)
how do I check if there's already a chat with the same recepient (or recepients) based on the chatId
There's several ways to tackle this;
One is that when an observer is added to each of the chats you are part of (.childAdded) each child node within that chat node will be returned to your app. This is good for two things - one is to populate the UI with the existing chat messages and secondly... you will then know who was involved with that chat. Keep those UID's in an array with the chat id, and before sending a chat to that person see if they exist in the array as an existing chat.
A second option is to query for all the chat's the users uid appears in (query using .observeSingleEvent). That will return all of the chat nodes they belong to and then have the uid's of who else they've chatting with and the chat id's as well.
Another option is when the chat is created, /chat_id_0, add a child node called /who_dat that keeps a list of who was invited to the chat
chats
chat_id_0
who_dat
uid_0: true
uid_1: true
uid_2: true
messages:
uid_0: "Hey there, Jesse"
uid_1: "Sup Bill?"
in this case uid_2 was also added to chat_id_0 but haven't heard from them yet.
Upvotes: 3