'Firebase realtime database structure in chat app

sorry for my bad English level, I'm from Argentina.

I have the following messages data structure in Firebase:

"messages"
   "-KezmqXSdKCNFFA432Uc___-KfCEwklG_y3naRDIUiY"
         "messageDate": "20170620"
         "messageTime": "18:44" 
         "message": "Hi"
   "-KezFDSAADFASFFS3221___-KASDF32324SDFASD1FS"
         "messageDate": "20170620"
         "messageTime": "22:23" 
         "message": "How are you?"

Where -KezmqXSdKCNFFA432Uc, -KfCEwklG_y3naRDIUiY, -KezFDSAADFASFFS3221 and -KASDF32324SDFASD1FS are users.

My problem is that I created a childEventListener in "messages" node to receive new users messages but I am receiving all the new messages of all the users (I'm logged in one user per app) because my childListener is in "messages" node.

Is it correct that if I have 1000 users when adding a message, a new message reaches the 1000 users? (Assuming that within the app, you can check to which user that message belongs).

Thanks!



Solution 1:[1]

Thanks to @Linxy for a brilliant answer

I have created a firebase database regarding @Linxy answer

enter image description here

Here is the complete JSON export

{
  "Chats" : {
    "-Lsfsd234xda" : {
      "lastMessageSent" : "-LrDEBo1-Message",
      "members" : [ "-LrDEBoLokW-5mhaT3ys", "-LrDEBoLokW-5mhaT3yz" ],
      "more_properties" : "goes here"
    }
  },
  "Users" : {
    "-LrDEBoLokW-5mhaT3ys" : {
      "id" : "-LrDEBoLokW-5mhaT3ys",
      "userDisplayName" : "Qadir Hussain",
      "userEmail" : "[email protected]",
      "userPhotoUrl" : "https://lh3.googleusercontent.com/a-/AAuE7XXXXXXXXX"
    },
    "-LrDEBoLokW-5mhaT3yz" : {
      "id" : "-LrDEBoLokW-5mhaT3yz",
      "userDisplayName" : "Ishaq Bhojani",
      "userEmail" : "[email protected]",
      "userPhotoUrl" : "https://lh3.googleusercontent.com/a-/AAuE7mB3KTbXXXXXXXX"
    }
  },
  "chatMessages" : {
    "-Lsfsd234xda" : {
      "-LrDEBo-MessageUID" : {
        "message" : "Hi there!",
        "messageDate" : "10/10/2019",
        "messageTime" : "10:16pm",
        "sentBy" : "-LrDEBoLokW-5mhaT3ys"
      },
      "-LrDEBo1-MessageUID" : {
        "message" : "Hello",
        "messageDate" : "10/10/2019",
        "messageTime" : "10:17pm",
        "sentBy" : "-LrDEBoLokW-5mhaT3yz"
      }
    }
  },
  "userChats" : {
    "-LrDEBoLokW-5mhaT3ys" : {
      "0" : "-Lsfsd234xda",
      "1" : "-Lsfsd234xda1",
      "chatUID" : "-Lsfsd234xda"
    }
  }
}

Solution 2:[2]

I know it's late to answer but for future readers although Linxy's answer is neater, I would like to point out a more efficient one having been tried both structures:

ChatMessages
   smallerUID_biggerUID
      messageUID
         sentBy : userUID
         messageDate : ""
         message : ""
      .
      .
   .
   .
UserChats
   userUID
      pairUID
        lastMessage : ""       
      .
      .
   .
   .

In this way, instead of first finding out the chatId then finding out which user is associated with that chatId, we can directly search which users should appear in our active chat tab and get thouse users' information (username, profilePicture). The reason for that is we can always calculate the chatId if we know the user's id we would like to message with. So for the message tab, we calculate the chatId (smallerUID_biggerUID) in client side and search for the messages in referencing it.

Solution 3:[3]

In order to structure your database, please read this post: Structuring your Firebase Data correctly for a Complex App. You'll find here for sure the answer to your question.

As a conclusion, try to flatten(denormalize) your database as much as possible.

Hope it helps.

Solution 4:[4]

this structure doesn't support what you want to do, it better to change it by using something like channels, where a channel contains the messages between two persons, so when any one of them send a message the other one will be notified.

Solution 5:[5]

{
    "users": {
        "userId": {
            "conversations": {
                "conversationId": {
                    "unseenCount": 0
                },
                "conversationId2": {
                    "unseenCount": 3
                }
        }
    },
    "conversations": {
        "conversationId": {
            "displayedMessage": "Message",
            "members": {
                "userId1": true,
                "userId2": true
            },
            "messages": {
                "messageId": {
                    "type": "text",
                    "text": "Hello",
                    "createdAt": "",
                    "senderId": "userId",
                    "status": "sent",
                    "payload": ""
                }
            },
            "lastMessage": "my last message"
        }
}

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shiv Kumar Baghel
Solution 2 Denton
Solution 3 Alex Mamo
Solution 4 Oussema Aroua
Solution 5 Daniel Lessa