聊天应用中的 Firebase 实时数据库结构
Firebase realtime database structure in chat app
对不起,我的英语水平不好,我来自阿根廷。
我在 Firebase 中有以下消息数据结构:
"messages"
"-KezmqXSdKCNFFA432Uc___-KfCEwklG_y3naRDIUiY"
"messageDate": "20170620"
"messageTime": "18:44"
"message": "Hi"
"-KezFDSAADFASFFS3221___-KASDF32324SDFASD1FS"
"messageDate": "20170620"
"messageTime": "22:23"
"message": "How are you?"
其中 -KezmqXSdKCNFFA432Uc、-KfCEwklG_y3naRDIUiY、-KezFDSAADFASFFS3221 和 -KASDF32324SDFASD1FS 是用户。
我的问题是我在 "messages" 节点中创建了一个 childEventListener 来接收新用户的消息,但我收到了所有用户的所有新消息(我每个应用程序登录一个用户)因为我childListener 在 "messages" 节点中。
如果我在添加消息时有1000个用户,一条新消息到达这1000个用户是否正确? (假设在应用程序中,您可以检查该消息属于哪个用户)。
谢谢!
这个结构不支持你想做的事情,最好用通道之类的东西来改变它,其中一个通道包含两个人之间的消息,所以当任何一个人向另一个人发送消息时会收到通知。
为了构建您的数据库,请阅读此 post:Structuring your Firebase Data correctly for a Complex App。您肯定会在这里找到问题的答案。
作为结论,请尝试尽可能扁平化(非规范化)您的数据库。
希望对您有所帮助。
如果你做一个类似这样的结构:
-chats
- chatUID
- members
- userUID
- lastMessageSent:messageUID
- ... more properties
-chatMessages
- chatUID
- messageUID
- sentBy: userUID
- messageDate:""
- messageTime:""
- message:""
-userChats
- userUID
- chatUID
您可以将侦听器附加到 /userChats/userUID,这将显示活动聊天,将侦听器附加到 /chatMessages/chatUID,它将获取特定聊天对话的所有聊天消息。
这种方式设置 firebase 安全规则要容易得多,用户只会收到他们分开的聊天消息。
{
"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"
}
}
}
我认为这将是最好的结构:
{
messages: {
A8Fcn28ak9ask46: {
chat_id: "combination of sender and receivers number",
sender_id: "person sending the message",
receiver_id: "person send it to",
text: "message that the user types",
timestamp: "123981849404"
},
...
}
}
然后当你得到结果时,你可以通过chat_id的正向和反向过滤,这将得到两个人之间的对话。
希望对您有所帮助。
感谢@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-5mhaT3yz",
"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"
}
}
}
我知道现在回答已经晚了,但对于未来的读者来说,虽然 Linxy 的回答更简洁,但我想指出一个更有效的方法,已经尝试了两种结构:
ChatMessages
smallerUID_biggerUID
messageUID
sentBy : userUID
messageDate : ""
message : ""
.
.
.
.
UserChats
userUID
pairUID
lastMessage : ""
.
.
.
.
通过这种方式,我们可以直接搜索哪些用户应该出现在我们的活动聊天选项卡中,并获取这些用户的信息(用户名、个人资料图片),而不是先找出 chatId,然后找出与该 chatId 相关联的用户).这样做的原因是,如果我们知道我们想要发送消息的用户 ID,我们总是可以计算 chatId。因此对于消息选项卡,我们在客户端计算 chatId (smallerUID_biggerUID) 并在引用它时搜索消息。
对不起,我的英语水平不好,我来自阿根廷。
我在 Firebase 中有以下消息数据结构:
"messages"
"-KezmqXSdKCNFFA432Uc___-KfCEwklG_y3naRDIUiY"
"messageDate": "20170620"
"messageTime": "18:44"
"message": "Hi"
"-KezFDSAADFASFFS3221___-KASDF32324SDFASD1FS"
"messageDate": "20170620"
"messageTime": "22:23"
"message": "How are you?"
其中 -KezmqXSdKCNFFA432Uc、-KfCEwklG_y3naRDIUiY、-KezFDSAADFASFFS3221 和 -KASDF32324SDFASD1FS 是用户。
我的问题是我在 "messages" 节点中创建了一个 childEventListener 来接收新用户的消息,但我收到了所有用户的所有新消息(我每个应用程序登录一个用户)因为我childListener 在 "messages" 节点中。
如果我在添加消息时有1000个用户,一条新消息到达这1000个用户是否正确? (假设在应用程序中,您可以检查该消息属于哪个用户)。
谢谢!
这个结构不支持你想做的事情,最好用通道之类的东西来改变它,其中一个通道包含两个人之间的消息,所以当任何一个人向另一个人发送消息时会收到通知。
为了构建您的数据库,请阅读此 post:Structuring your Firebase Data correctly for a Complex App。您肯定会在这里找到问题的答案。
作为结论,请尝试尽可能扁平化(非规范化)您的数据库。
希望对您有所帮助。
如果你做一个类似这样的结构:
-chats
- chatUID
- members
- userUID
- lastMessageSent:messageUID
- ... more properties
-chatMessages
- chatUID
- messageUID
- sentBy: userUID
- messageDate:""
- messageTime:""
- message:""
-userChats
- userUID
- chatUID
您可以将侦听器附加到 /userChats/userUID,这将显示活动聊天,将侦听器附加到 /chatMessages/chatUID,它将获取特定聊天对话的所有聊天消息。
这种方式设置 firebase 安全规则要容易得多,用户只会收到他们分开的聊天消息。
{
"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"
}
}
}
我认为这将是最好的结构:
{
messages: {
A8Fcn28ak9ask46: {
chat_id: "combination of sender and receivers number",
sender_id: "person sending the message",
receiver_id: "person send it to",
text: "message that the user types",
timestamp: "123981849404"
},
...
}
}
然后当你得到结果时,你可以通过chat_id的正向和反向过滤,这将得到两个人之间的对话。
希望对您有所帮助。
感谢@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-5mhaT3yz",
"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"
}
}
}
我知道现在回答已经晚了,但对于未来的读者来说,虽然 Linxy 的回答更简洁,但我想指出一个更有效的方法,已经尝试了两种结构:
ChatMessages
smallerUID_biggerUID
messageUID
sentBy : userUID
messageDate : ""
message : ""
.
.
.
.
UserChats
userUID
pairUID
lastMessage : ""
.
.
.
.
通过这种方式,我们可以直接搜索哪些用户应该出现在我们的活动聊天选项卡中,并获取这些用户的信息(用户名、个人资料图片),而不是先找出 chatId,然后找出与该 chatId 相关联的用户).这样做的原因是,如果我们知道我们想要发送消息的用户 ID,我们总是可以计算 chatId。因此对于消息选项卡,我们在客户端计算 chatId (smallerUID_biggerUID) 并在引用它时搜索消息。