Databse Structure - abhiram-shaji/Langroove GitHub Wiki

1. Separate Users from Chats

Instead of using a combined chat ID as the document key, a chats collection should have its own unique identifiers (not tied to user IDs). This will allow for easier support of group chats or renaming chats.

2. Chats Collection

  • chats (collection)
    • chatId (document): A UUID or Firestore-generated document ID for the chat, not a combination of user IDs.
    • participants (array): An array of user IDs (e.g., ["Zb3U9omAYDRtROylSIb6MlPiZTj2", "ayYFbh8Frccb80et49oTYFNgXj63"]). This makes it flexible to expand to group chats.
    • isGroupChat (boolean): True if the chat is a group chat, False otherwise.
    • lastMessage (object): The last message sent in the chat (contains messageId, text, createdAt).

3. Messages Subcollection

Each chat has its own subcollection for messages. Messages should include metadata for both sender and recipient, and you could index these fields for faster retrieval if needed.

  • messages (subcollection)
    • messageId (document): Firestore auto-generated document ID or UUID.
    • text (string): The message content.
    • senderId (string): ID of the user who sent the message.
    • recipientId (string): ID of the recipient (can be omitted in group chats).
    • createdAt (timestamp): Timestamp of when the message was sent.
    • readBy (array): Array of user IDs who have read the message (useful for group chats).
    • attachments (optional object): Contains any file attachments (images, videos, etc.).

4. Indexes for Queries

  • createdAt (indexed): For efficient retrieval of messages in chronological order.
  • senderId and recipientId (indexed): Helps with querying specific conversations or user-specific searches.
  • readBy (indexed): For efficiently tracking read receipts.

Example Structure:

chats (collection)
 └── chatId (document)
      ├── participants: ["Zb3U9omAYDRtROylSIb6MlPiZTj2", "ayYFbh8Frccb80et49oTYFNgXj63"]
      ├── isGroupChat: false
      ├── lastMessage: {messageId: "abc123", text: "Hey!", createdAt: timestamp}
      └── messages (subcollection)
           └── messageId (document)
                ├── text: "Hello!"
                ├── senderId: "Zb3U9omAYDRtROylSIb6MlPiZTj2"
                ├── recipientId: "ayYFbh8Frccb80et49oTYFNgXj63"
                ├── createdAt: timestamp
                └── readBy: ["Zb3U9omAYDRtROylSIb6MlPiZTj2"]

Key Benefits:

  • Flexibility for Group Chats: The structure can easily scale for multiple participants.
  • Efficient Querying: Using createdAt, senderId, and recipientId as indexed fields ensures efficient retrieval.
  • Future-proofing: Allows you to add features like read receipts, file attachments, and last seen status without restructuring your database.