Structure a NoSQL database for a chat application (using FireBase)

13,220

Solution 1

Using the document-oriented database structure such Firestore, you can store the conversations as below;

{
   "chat_rooms":[
      {
         "cid":100,
         "members":[1, 2],
         "messages":[
           {"from":1, "to":2, "text":"Hey Dude! Bring it"},
           {"from":2, "to":1, "text":"Sure man"}
          ]
      },
      {
         "cid":101,
         "members":[3, 4],
         "messages":[
           {"from":3, "to":4, "text":"I can do that work"},
           {"from":4, "to":3, "text":"Then we can proceed"}
          ]
      }
   ]
}

Few examples of NoSQL queries you could run through this structure.

Get all the conversations of a logged-in user with the user id of 1.

db.chat_rooms.find({ members: 1 })

Get all the documents, messages sent by the user id of 1.

db.chat_rooms.find({ messages: { from: 1 } })

The above database structure is also capable of implementing in RDMS database as table relationships using MySQL or MSSQL. This is also can be implemented for group chat room applications.

This structure is optimized to reduce your database document reading usage which can save your money from paying more for infrastructure.

According to our above example still, you will get 2 document reads since we have 4 messages but if you store all the messages individually and run the query by filtering sender id, you will get 4 database queries which are the kind of massive amount when you have heavy conversation histories in your database.

Solution 2

One case for storing messages could look something like this:

"userMessages": 
    { "simplelogin:1": 
        { "simplelogin:2": 
            { "messageId1": 
                { "uid": "simplelogin:1", 
                  "body": "Hello!", 
                  "timestamp": Firebase.ServerValue.TIMESTAMP },
               "messageId2": { 
                  "uid": "simplelogin:2", 
                  "body": "Hey!", 
                  "timestamp": Firebase.ServerValue.TIMESTAMP } 
                 } 
             } 
         } 

Here is a fireslack example this structure came from. This tutorial builds an app like slack using firebase: https://thinkster.io/angularfire-slack-tutorial

If you want something more specific, more information would be helpful.

Share:
13,220
TareK Khoury
Author by

TareK Khoury

Updated on June 05, 2022

Comments

  • TareK Khoury
    TareK Khoury about 2 years

    Coming from years of using relational databases, i am trying to develop a pretty basic chat/messaging app using FireBase

    FireBase uses a NoSQL data structure approach using JSON formatted strings.

    I did a lot of research in order to understand how to structure the database with performance in mind. I have tried to "denormalize" the structure and ended up with the following:

    {
    
    "chats" : {
    
        "1" : {
            "10" : {
                "conversationId" : "x123332"
             },
            "17": {
                "conversationId" : "x124442"
            }
        }
    },
    
    "conversations" : {
    
        "x123332" : {
    
          "message1" : {
    
            "time" : 12344556,
            "text" : "hello, how are you?",
            "userId" : 10
          },
          "message2" : {
    
            "time" : 12344560,
            "text" : "Good",
            "userId" : 1
          }
        }
      }
    }
    

    The numbers 1, 10, 17 are sample user id's.

    My question is, can this be structured in a better way? The goal is to scale up as the app users grow and still get the best performance possible.

  • Ruben
    Ruben almost 7 years
    but what is simplelogin2 logs in, how will you find the chat messages for this user?
  • Luke Schlangen
    Luke Schlangen almost 7 years
    You would probably store the same information under simplelogin2. Yes, it duplicates information in the database, but that's often the price you pay for quick query times in NoSQL.
  • Ruben
    Ruben almost 7 years
    do you have more examples maybe? it's so weird and counter intuitive to have everthing twice or more in the database. on the firebase website (firebase.google.com/docs/database/web/structure-data) there is a different structure for a chat app but I don't get how you can read this data, there are keys one, two, three.. but if I'm logged in as 'ghopper', how can I find the correct key for the current chat