Dani
Dani

Reputation: 3637

Multi-users chat room data structure in Firebase Database

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:

enter image description here

enter image description here

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

Answers (1)

Jay
Jay

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

Related Questions