How to structure Firebase database for a scalable chat app

Varun Raj
Varun Raj, Co-founder and CTO
How to structure Firebase database for a scalable chat app

Messengers are very common these days, and almost all apps like the ones for online shopping, a game or even file sharing apps has a kind of messaging medium which enables your customers/users to communicate between each other. This gives the user a bigger boundary around your app. And if you’re looking to build one such messenger or a communication medium for your Firebase project, probably you’re at the right place as you’ll need to plan for a proper long-lived data structure.

Here we’ll be using the Firebase’s real-time database in this article.

Defining the nodes

To get started, hope you already have a sample app and so I’m skipping the project creation and setup process. Also, I believe you have a user’s node where you have all the information of the corresponding user of your application. Now let’s define the node we’ll be using to get the architecture up and running.

User’s Node

As I mentioned earlier, I hope you already have a user’s node, and now we just have to create a sub-node called conversations where we’ll have the information about the conversations that belong to that user. Each child of the conversation node has the key pointing to the other user’s ID. The child node has the ID of the conversation and the unseenCount. The reason to have the unseenCount under the user node is that it’s different for both the users.

With this node, we can easily get all the conversations of the corresponding user.

* users []
- conversations []
- {userId}
- conversationId: {conversationId}
- unseenCount: {number}

Conversation Nodes

Now that the user based conversation info is defined in the user node, next is to create a conversations node under root node of the application where we’ll have all the conversations between the entire user base. This will be identified by the data under users node while reading or listing the conversations.

The conversations node has the child nodes each which holds the complete data of the corresponding conversation. The key nodes to notice here are members, messages, lastMessageTime, and displayMessage

Members Node

The members node has the list of users who belong to a part of that conversation. With this node, we can list the members of the conversations. This also helps us send notifications when a new message has been sent to the group.

Messages Node

Messages node is where we’ll be hosting all the messages in that conversation. It’ll be a big list of data, make sure you paginate while listing as it might even reach up to thousands and millions. Each node in the message has few basic data like text, createdAt, senderId. If you want to build a rich messenger you can also have additional data, you can include data like attachments, media, etc.

* conversations []
- {conversationId}
- displayMessage: {string}
- members []
- {userId}: {true}
- messages []
- {messageId}
- text: ""
- createdAt
- senderId
- lastMessageTime:

The above two nodes are more than enough for building a simple messenger for your application, But if you’re looking for the more rich experience like reading receipts, reply to messages, etc the schema changes a bit to allow those features, and we’ll soon get back to you with that!