Structuring Data for Chat App in Firebase

Firebase data structure for one to chat app or private

When a user publishes a product (the potential seller), you'll need to associate their user ID with that product. Based on that, the interested user (potential buyer) can make the connection.

Given your other requirements, I'd nest the chats:

chats: {
uid1_uid2_productid: {
pushid: { message: ..., timestamp: ..., sender: ... },
pushid: { message: ..., timestamp: ..., sender: ... }
}
}

And then associate these chats with the correct users in user-specific lists:

user_chats: {
uid1: {
uid1_uid2_productid: true
},
uid2: {
uid1_uid2_productid: true
}
}

Instead of true you could also store a value (or more properties) that help you display the list of chats for that specific user.


If you want each user to have a completely separate copy of the chat/room, your easiest approach is to duplicate the rooms. So:

chats: {
uid1_uid2_productid: {
pushid: { message: ..., timestamp: ..., sender: ... },
pushid: { message: ..., timestamp: ..., sender: ... }
}
uid2_uid1_productid: {
pushid: { message: ..., timestamp: ..., sender: ... },
pushid: { message: ..., timestamp: ..., sender: ... }
}
}

And then:

user_chats: {
uid1: {
uid1_uid2_productid: true
},
uid2: {
uid2_uid1_productid: true
}
}

Firebase realtime database structure in chat app

If you do a structure like similar to this:

-chats
- chatUID
- members
- userUID
- lastMessageSent:messageUID
- ... more properties

-chatMessages
- chatUID
- messageUID
- sentBy: userUID
- messageDate:""
- messageTime:""
- message:""

-userChats
- userUID
- chatUID

you can attach a listener to /userChats/userUID, which will display active chats, and a listener to /chatMessages/chatUID, which will get all chat messages for a specific chat conversation.

This way is a lot easier to setup firebase security rules, and users will only receive chat messages which they are apart of.

How to structure chat with firebase

When you start building an app, first you need to think about the database which is most appropriate for it. If you think about Firestore, you need to know that Cloud Firestore's pricing model for applications that perform very large numbers of small reads and writes per second per client could be significantly more expensive than a similarly performing app in the Realtime Database.

There are also are a few differences between these two databases. If you want to go ahead with Firebase Realtime Database you need to know that you cannot query over multiple properties and it usually involves duplication data or client-side filtering, which in some cases is some kind of messy. Realtime Database does not scale automatically while Firestore, does.

Regarding how to structure a database for a chat application, you need to know that there is no perfect structure for doing that. You need to structure your database in a way that allows you to read/write data very easily and in a very efficient way. Firebase official documentation explains how can you structure a database for a chat app. If you want something more complex, please read this post, Structuring your Firebase Data correctly for a Complex App.

For a better understanding, I recommend you as well to take Firebase free courses, Firebase in a Weekend: Android.

So it's up to you to decide which one is better for you.

P.S: If you are interested, I have also explained in one of my tutorials how you can create a Chat App using Cloud Firestore and Kotlin.

Firebase database structure for chat application

It sounds like you want to:

  1. Have chat "rooms" between users
  2. Show a list of each user's chat rooms, with the latest message for that room

If those are your requirements, I'd model precisely those in your database.

So for each chat room (a chat between a certain set of users), model the messages for that room:

chats: {
$roomId: {
$messageId: {
senderId: "..."
message: "..."
}
}
}

Now for each user, model a separate list of their chats and the latest message:

userRooms: {
$uid: {
$roomId: {
"message: "..."
}
}
}

Now whenever a user posts a message to a room, you will need to push that message to /chats/$roomId and for each user in that chat room write the message to /userRooms/$uid/$roomId (overwriting the exiting message there).

This type of data duplication is known as fanning out data, because you're spreading a single snippet of information over multiple places in the database. It is quite common in NoSQL databases, and is part of the reason they scale so well: they trade write complexity for read performance.

Firebase database structure for one-on-one messaging?

How would a logged in user be associated with any given chat they participated into?

Right now your structure doesn't seem to allow for an easy handling of this, given that "user_id" are nested within the chat document.

Personally, here's what I would do.

First I would create 2 collections, one called chats one called users.
users would have the following structure:

{"users": {
"userID_1": {
"name": "John",
"surname": "Smith",
"chats": [
"chatID_1",
"chatID_2",
"chatID_3"
]
},
"userID_2": {
"name": "Betty",
"surname": "Sue",
"chats": [
"chatID_1",
"chatID_4"
]
}
}}

Chats would instead be stored like this:

{"chats": {
"chatID_1": {
"chatName": "foo",
"otherInfo": "..",
"messages": {
"messageID_1": {"senderID": "..", "message": "..", "timestamp": 999},
"messageID_2": {"senderID": "..", "message": "..", "timestamp": 999}
}
},
"chatID_2": {
"chatName": "bar",
"otherInfo": "..",
"messages": {
...
}
}
}}

This way, when a user is logged in, you can easily fetch all his chats by querying users.userID.chats, and retrieve the content of any selected chat by querying chats.chatID.messages.

Firebase data structure for chat app

The only issue you may run in to is how the data is called. Note that when you call the 'Chat Log', because it is a child of 'Users' and 'chatPartners', you will be calling the data of everything in that branch, essentially loading every piece of data in the database under 'Users', which is time and performance sensitive.



Related Topics



Leave a reply



Submit