Firebase一对一聊天应用程序结构和按值获取子级
我尝试用firebase和angular构建一对一聊天应用程序。我正在使用firebase文档中推荐的结构,但我在数据检索方面遇到了麻烦Firebase一对一聊天应用程序结构和按值获取子级,firebase,firebase-realtime-database,nosql,Firebase,Firebase Realtime Database,Nosql,我尝试用firebase和angular构建一对一聊天应用程序。我正在使用firebase文档中推荐的结构,但我在数据检索方面遇到了麻烦 { "chats" : { "one" : { "lastMessage" : "test" } }, "members" : { "one" : { "rebel" : true, "redboy" : true } }, "messages" : { "one"
{
"chats" : {
"one" : {
"lastMessage" : "test"
}
},
"members" : {
"one" : {
"rebel" : true,
"redboy" : true
}
},
"messages" : {
"one" : {
"-KS1R6b-1TdVASQL4tj7" : {
"createdAt" : 1474288450158,
"text" : "hgagagagaga",
"userId" : "rebel"
},
"-KS1aZxqX3_PpjNdyiA7" : {
"createdAt" : 1474291191857,
"text" : "hhh",
"userId" : "redboy"
}
}
}
}
如何使用firebase查询获取用户“叛军”聊天记录。或者我应该在用户的根目录上存储聊天ID
没有WHERE
子句,这种结构使我感到困惑
更新:
如果我将chatIds添加到用户的根目录,这可以解决我的问题,但不能确定它是否正确。看来是对的
"users" : {
"rebel" : {
"age" : 3,
"chats" : {
"one" : true
},
"name" : "rbl"
},
"redboy" : {
"age" : 5,
"chats" : {
"one" : true
},
"name" : "rb"
}
}
是的,您需要将聊天id存储在用户的根目录下,其值为true,以检索所有聊天记录以及随后的消息。在使用Firebase(以及大多数其他NoSQL解决方案)时,请遵循此原则,您会发现您经常需要按照应用程序使用数据的方式对数据进行建模 您当前的数据结构允许您轻松找到特定聊天室的成员 从技术上讲,您可以查询以查找特定成员的聊天室:
ref.child('members').orderByChild('rebel').equalTo(true)
但这需要为每个用户定义一个索引,该索引不可伸缩(因为必须为每个用户手动添加索引):
最常见的解决方案是(如前所述)对数据进行建模,以允许进行所需的查询。由于要查找每个用户的聊天室,因此应展开模型以存储每个用户的聊天室:
{
"rules": {
"members": {
".indexOn": ["rebel", "redboy"]
}
}
}
"memberships" : {
"rebel" : {
"one": true
},
"redboy" : {
"one" true
}
},
如您所见,这里我们保留成员的反向索引
现在,您可以通过以下方式轻松确定用户的房间:
ref.child('memberships/rebel').on('child_added', ...
我看到你在你的问题中增加了一个类似的结构。主要区别在于我将其添加为顶级结构。这是Firebase的常见模式,因为它可以更容易地保护数据并仅检索数据的一个子集
为了更好地理解这一点,我推荐这篇文章。您的问题中包含了JSON树的图片。请将其替换为实际的JSON作为文本,您可以通过单击Firebase数据库控制台中的导出按钮轻松获得该文本。将JSON作为文本使其具有可搜索性,允许我们轻松使用它来测试您的实际数据,并在我们的答案中使用它,一般来说,这是一件好事。@FrankvanPuffelen您是对的,我将其替换为Hanks Frank这对我来说是一个非常好的答案,我将把我的添加到顶层,因为你建议我这里有一个关于@FrankvanPuffelen的后续问题,当用户redboy想要向rebel发送消息时会发生什么?redboy会先创建一个新聊天,然后将该聊天添加为memberships/rebel中的节点吗?这是正确的方法吗?所有这些逻辑都会放在客户端应用程序中吗?