Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to structure Firestore database in chat app?

The simplest way of storing chat messages is probably this:

message:
 -message1 {
   "user1"
   "user2"
   "message"
   "date"
  }
 -message2
 -message3

When the app grows in size (a lot of messages), and operations on database are done with .whereEqualTo are there any disadvantages of structuring chat app messages this way? Like with database iterating through all messages ?

Because if there are problems with this approach, i've seen for example this way of structuring database, that would segregate messages in different chat rooms

chats: {
    -chat1 {
      "lastMessage"
      "timestamp"
      "users": {user1, user2}
    }
    -chat2
    -chat3
  }

messages: {
 -chat1 {
  "message"
  "date"
 }
}

But in this example, adding new message would require user to make 2 write operations, one writing new message and one updating chat document with new lastMessage and timestamp client-side, or creating a cloud function to update chat document with new values, when new message is added.

So, is the first option valid, or should I go with something like the second example?

like image 488
Wiktor Avatar asked Jan 02 '19 14:01

Wiktor


People also ask

What is FireStore database?

Firestore Database consists of 3 things 1 Collections - Collections are nothing but a set of document. 2 Documents - Documents are set of sub-collections and field. 3 Fields - Field consists of attribute and value. The values are of the type of string, number, boolean, map, array, null, timestamp, geopoints and reference.

How do I create a FireStore in Firebase?

In your Firebase console, go to Database, and create a Cloud FireStore (Beta for now). After that, you could a Collection with the name Chat. Then create a Document with the name Message. Something as below After that, you need to add the rule to access to write and read your FireStore. I do a simple one by allow all to write/read from it.

How do I create a chat message in Firebase?

In your Firebase console, go to Database, and create a Cloud FireStore (Beta for now). After that, you could a Collection with the name Chat. Then create a Document with the name Message.

How to send message over to FireStore?

Then create a Document with the name Message. Something as below After that, you need to add the rule to access to write and read your FireStore. I do a simple one by allow all to write/read from it. Go to the Rules tab (next to Data tab), then add the bold rule below The main part is to send message over to the store as below.


1 Answers

What you've offered as the first option is close to how you'd model this in a relation database in a tblMessages. Such a literal translation is seldom your best option in NoSQL databases, since they have very different trade-offs. For example, you've already noticed that you need to perform a query on two fields to get the messages between two users.

When modeling data on a NoSQL database, I usually recommend modeling in your database for what you see on your screen. So if your chat app has the concept of chat rooms (i.e. persistent chats between specific groups of people), I'd model those in your database too.

In Cloud Firestore that means that you'd have a top-level collection with a document for each chat room, and then a subcollection under each such document with the messages for that chat room:

ChatRooms (collection)
  ChatRoom1 (document)
    Messages (collection)
      Message1_1 (document)
      Message1_2 (document)
  ChatRoom2 (document)
    Messages (collection)
      Message2_1 (document)
      Message2_2 (document)

With this model you don't need to query to show the messages in a chat room, but can instead just load (all) the messages straight from the subcollection for that room. It also has the advantage that you partition the rooms, meaning that writes can scale much better.

I typically recommend modeling the chat room document IDs after the participants in the room, so that you can easily reconstruct the ID based on the participants. But there are more valid options for this.

like image 90
Frank van Puffelen Avatar answered Sep 25 '22 08:09

Frank van Puffelen