用于双向链接的Firebase查询

用于双向链接的Firebase查询,firebase,Firebase,我正在设计一个类似Facebook Messenger的聊天应用程序。我当前的两个根节点是聊天和用户。用户有一个相关的聊天列表users/user/chats,聊天通过autoID添加到chats节点chats/a151jl1j6。该节点存储信息,如消息列表、最后一条消息的时间、是否有人在键入等 我正在努力解决的问题是如何定义聊天中的两个用户。最初,我在users/user/chats节点中将对另一个用户的引用作为chatId键的值,但我认为这是一个坏主意,因为我曾经想要进行群聊 更符合逻辑的是

我正在设计一个类似Facebook Messenger的聊天应用程序。我当前的两个根节点是
聊天
用户
。用户有一个相关的聊天列表
users/user/chats
,聊天通过autoID添加到
chats
节点
chats/a151jl1j6
。该节点存储信息,如消息列表、最后一条消息的时间、是否有人在键入等

我正在努力解决的问题是如何定义聊天中的两个用户。最初,我在
users/user/chats
节点中将对另一个用户的引用作为chatId键的值,但我认为这是一个坏主意,因为我曾经想要进行群聊

更符合逻辑的是有一个
chats/chat/members
节点,我在其中定义
userId:true,user2id:true
。我的问题是如何有效地查询它。例如,如果用户要与用户创建一个新的聊天,我们要检查他们之间是否已经存在聊天。我不知道如何查询“查找成员包含
currentUserId
friendUserId
的聊天”,或者这是否是一种有效的非规范化方式


有什么提示吗?

我记得不久前我也遇到过类似的问题。我是如何解决的:

  • 用户1具有唯一的ID
    id1
  • 用户2具有唯一的ID
    id2
聊天室的ID不是通过autoId添加新的聊天室
chats/a151jl1j6
,而是
id1----|124;--id2
(超原始人类可读delimeter)

(这正是您最初的建议)

最初,我在users/user/chats节点中将对另一个用户的引用作为chatId键的值,但我认为如果我想要组聊天,这是个坏主意

俗话说:


路径中可以存在的用户ID数量可能有限制-您可以始终散列值…

我记得不久前我遇到过类似的问题。我是如何解决的:

  • 用户1具有唯一的ID
    id1
  • 用户2具有唯一的ID
    id2
聊天室的ID不是通过autoId添加新的聊天室
chats/a151jl1j6
,而是
id1----|124;--id2
(超原始人类可读delimeter)

(这正是您最初的建议)

最初,我在users/user/chats节点中将对另一个用户的引用作为chatId键的值,但我认为如果我想要组聊天,这是个坏主意

俗话说:


路径中可以存在的用户ID数量可能有限制-您可以始终散列值…

尽管将ID设置为
id1----||--id2
格式的想法肯定能完成任务,如果你希望有一个大的群体,并且你必须考虑到
id2----||--id1
比较,那么它可能无法扩展,当你在一次对话中有更多的人时,这也会变得更加复杂。如果你不需要担心庞大的群体,你应该这样做

实际上,我会使用autoId
chats/a151jl1j6
,因为您可以免费获得它。构造数据的建议方法是使autoId成为具有相关子对象的其他节点中的键。因此,
chats/a151jl1j6
将包含会话元数据,
members/a151jl1j6
将包含该会话中的成员,
messages/a151jl1j6
将包含消息等等

“聊天”:{
“a151jl1j6”:{}
“成员”:{
“a151jl1j6”:{
“user1”:正确,
“user2”:true
}
}
“信息”:{
“a151jl1j6”:{}
这种方法的“低效”之处在于查询同时包含user1和user2的会话。建议的方法是为每个用户创建对话索引,然后查询
成员
数据

“user1”:{
“聊天”:{
“a151jl1j6”:正确
}
}
在查询具有扁平化数据结构的关系时,这是一种权衡。查询速度很快,因为您只处理数据的一个子集,但最终会得到大量重复数据,在您修改/删除时需要考虑这些重复数据,即当用户离开聊天会话时,您必须更新多个结构


参考资料:

虽然将ID设置为
id1--id2
格式的想法肯定能完成任务,但如果您希望拥有大量的团队,并且您必须考虑到
id2--id1
比较,这也会变得更加复杂,因为在一次对话中有更多的人参与。如果你不需要担心庞大的群体,你应该这样做

实际上,我会使用autoId
chats/a151jl1j6
,因为您可以免费获得它。构造数据的建议方法是使autoId成为具有相关子对象的其他节点中的键。因此,
chats/a151jl1j6
将包含会话元数据,
members/a151jl1j6
将包含该会话中的成员,
messages/a151jl1j6
将包含消息等等

“聊天”:{
“a151jl1j6”:{}
“成员”:{
“a151jl1j6”:{
“user1”:正确,
“user2”:true
}
}
“信息”:{
“a151jl1j6”:{}
这种方法的“低效”之处在于查询同时包含user1和user2的会话。建议的方法是为每个用户创建对话索引,然后查询
成员
数据

“user1”:{
“聊天”:{
“a151jl1j6”:正确
}
}
在查询具有扁平化数据结构的关系时,这是一种权衡。查询速度很快,因为您只处理数据的一个子集,但最终会产生大量重复数据,在修改/删除时需要考虑这些重复数据