聊天应用中的Firebase实时数据库结构

Agu*_*tin 3 android structure firebase firebase-realtime-database

抱歉我的英语水平不好,我来自阿根廷.

我在Firebase中有以下消息数据结构:

"messages"
   "-KezmqXSdKCNFFA432Uc___-KfCEwklG_y3naRDIUiY"
         "messageDate": "20170620"
         "messageTime": "18:44" 
         "message": "Hi"
   "-KezFDSAADFASFFS3221___-KASDF32324SDFASD1FS"
         "messageDate": "20170620"
         "messageTime": "22:23" 
         "message": "How are you?"
Run Code Online (Sandbox Code Playgroud)

其中-KezmqXSdKCNFFA432Uc,-KfCEwklG_y3naRDIUiY,-KezFDSAADFASFFS3221-KASDF32324SDFASD1FS是用户.

我的问题是我在"messages"节点中创建了一个childEventListener来接收新用户的消息但是我收到了所有用户的所有新消息(我每个应用程序登录一个用户)因为我的childListener在"messages"节点中.

如果我在添加邮件时有1000个用户,新邮件会到达1000个用户,这是否正确?(假设在应用程序中,您可以检查该消息所属的用户).

谢谢!

Lin*_*nxy 29

如果你做一个类似于这样的结构:

-chats
   - chatUID
       - members
           - userUID
       - lastMessageSent:messageUID
       - ... more properties  

-chatMessages
   - chatUID
     - messageUID
         - sentBy: userUID
         - messageDate:""
         - messageTime:""
         - message:""

-userChats
    - userUID
       - chatUID
Run Code Online (Sandbox Code Playgroud)

你可以将一个监听器附加到/ userChats/userUID,它将显示活动的聊天记录,以及一个监听器/ chatMessages/chatUID,它将获取特定聊天对话的所有聊天消息.

这种方式设置firebase安全规则要容易得多,用户只会收到他们所处的聊天消息.

  • @Linxy用户A和用户B在聊天室中,并且都向/ chatMessages / chatUID添加了一个侦听器。现在,如果userA在`chatUid`中推送了一条新消息,则两个用户A&B都将通过其侦听器收到此新消息。这对用户A来说不是浪费带宽,因为他自己推送了带宽。是否可以具有Db结构,以便userA仅侦听来自userB的消息? (3认同)
  • 我知道了。无论如何,我需要从 firebase 实现函数和触发器,对吗? (2认同)

Qad*_*ain 5

感谢@Linxy 的精彩回答

我已经创建了一个关于 @Linxy 答案的 firebase 数据库

在此处输入图片说明

这是完整的 JSON 导出

{
  "Chats" : {
    "-Lsfsd234xda" : {
      "lastMessageSent" : "-LrDEBo1-Message",
      "members" : [ "-LrDEBoLokW-5mhaT3ys", "-LrDEBoLokW-5mhaT3yz" ],
      "more_properties" : "goes here"
    }
  },
  "Users" : {
    "-LrDEBoLokW-5mhaT3ys" : {
      "id" : "-LrDEBoLokW-5mhaT3ys",
      "userDisplayName" : "Qadir Hussain",
      "userEmail" : "XXXXX.XXXX@gmail.com",
      "userPhotoUrl" : "https://lh3.googleusercontent.com/a-/AAuE7XXXXXXXXX"
    },
    "-LrDEBoLokW-5mhaT3yz" : {
      "id" : "-LrDEBoLokW-5mhaT3ys",
      "userDisplayName" : "Ishaq Bhojani",
      "userEmail" : "XXXXXXX.XXXXXX@gmail.com",
      "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"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道现在回答已经晚了,但对于未来的读者来说,尽管 Linxy 的答案更简洁,但我想指出一种更有效的答案,已经尝试了两种结构:

ChatMessages
   smallerUID_biggerUID
      messageUID
         sentBy : userUID
         messageDate : ""
         message : ""
      .
      .
   .
   .
UserChats
   userUID
      pairUID
        lastMessage : ""       
      .
      .
   .
   .
Run Code Online (Sandbox Code Playgroud)

这样,我们就可以直接搜索哪些用户应该出现在我们的活动聊天选项卡中并获取这些用户的信息(用户名、个人资料图片),而不是首先查找 chatId,然后查找与该 chatId 关联的用户。原因是,如果我们知道想要发送消息的用户 ID,我们总是可以计算出 chatId。因此,对于消息选项卡,我们在客户端计算chatId(smallerUID_biggerUID)并搜索引用它的消息。