2
votes

I am designing a chat app using cloud firestore and the schema looks something like this :

Each 1:1 chat is created inside a chats collection. Each chats collection will have a set of fields and a sub collection. Each sub collection will have all the messages. It looks something like this -

/chats

* id (auto gen)
* channel ( string type - sort(uid1 , uid2) )
* uid1
* uid2
* createdTime
* lastMessageSentTime
* messages (sub collection) 
    * fromUid
    * toUid
    * content
    * sendTime

To show the initial chat screen, with all users the user has been chatting with, I query the /chats collection and sort the results by lastMessageSentTime.

One problem I see with this design is that I need to update the lastMessageSentTime for every message sent or received. Is there a way I can avoid this double writing ?

Can I use the messages sub collection's sendTime to somehow show the first chat screen or is there another way out ?

Thanks in advance !

2

2 Answers

3
votes

There is no way to query the top-level chats collection based on a value in the messages subcollection.

So you have two options:

  1. Write the lastMessageSentTime into the chat room document, and update it every time you write a message for that chat room. That's your current proposal.

  2. Determine the correct order on reading the data. So you first load all chat rooms, and then load the most recent message for each chat room.

Developers who are new to NoSQL databases often start from the second option, while more experienced NoSQL developers will typically pick the first as it leads to a more simple and scalable read operation.

1
votes

If you want to sort documents in a collection with one query, you can only use the documents in that one collection. You can't "join" other documents from other collections to change the results of the query. So, the way you have it now, you have to "double write" the timestamp. Duplicating data like this is very common in NoSQL type databases.