【问题标题】:Firebase query for bi-directional link双向链接的 Firebase 查询
【发布时间】:2016-05-24 00:15:44
【问题描述】:

我正在设计一个类似于 Facebook Messenger 的聊天应用程序。我当前的两个根节点是chatsusers。用户有一个关联的聊天列表users/user/chats,并且聊天是通过chats 节点chats/a151jl1j6 中的自动ID 添加的。该节点存储诸如消息列表、最后一条消息的时间、是否有人正在打字等信息。

我正在苦苦挣扎的是在哪里定义聊天中的两个用户。最初,我在users/user/chats 节点中将其他用户的引用作为chatId 键的值,但我认为这是一个坏主意,以防我想要群聊。

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

有什么提示吗?

【问题讨论】:

    标签: firebase


    【解决方案1】:

    虽然使用id1---||---id2 格式的 id 的想法肯定可以完成工作,但如果您希望拥有大型组并且您必须考虑 id2---||---id1 比较,这可能会变得更加复杂更多的人在交谈。如果您不需要担心大型团体,您应该这样做。

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

    "chats":{
        "a151jl1j6":{}}
    
    "members":{
        "a151jl1j6":{
            "user1": true,
            "user2": true
        }
    }
    
    "messages":{
        "a151jl1j6":{}}
    

    这得到一点“低效”的部分是查询包括 user1 和 user2 的对话。推荐的方法是为每个用户创建一个对话索引,然后查询members数据。

    "user1":{
        "chats":{
            "a151jl1j6":true
        }
    }
    

    在使用扁平数据结构查询关系时,这是一种权衡。查询速度很快,因为您只处理数据的子集,但最终会在修改/删除时得到大量重复数据,即当用户离开聊天对话时,您必须更新多个结构。

    参考:https://firebase.google.com/docs/database/ios/structure-data#flatten_data_structures

    【讨论】:

    • 非常感谢!因此,您是说要检查用户 x 的现有转换,我遍历我的聊天并检查每个聊天以查看用户 x 是否在其中?这将查询限制为我拥有的聊天数量,这应该很便宜,对吧?
    • 是的,这也取决于您应用的用户体验;大多数聊天应用程序都有一个显示所有聊天列表的屏幕,因此您已经在应用程序中本地拥有现有对话,因此您甚至可以在本地进行查询,因为 firebase 会保持同步。但是,如果您希望人们从其他地方开始对话并且需要大量检查现有对话,您可以在弹性搜索 (github.com/firebase/flashlight) 中另外为对话及其成员编制索引,并且只需一个查询即可执行更复杂的搜索。
    【解决方案2】:

    我记得我前段时间遇到过类似的问题。我是如何解决的:

    • 用户 1 具有唯一 ID id1
    • 用户 2 有一个唯一 ID id2

    聊天 ID 不是通过 autoId chats/a151jl1j6 添加新聊天,而是id1---||---id2 (超原始的人类可读分隔符)

    (这正是你最初的建议)

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

    有句话说:https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it

    路径中可以存在多少用户 ID 可能存在限制 - 您始终可以散列值...

    【讨论】:

    • 所以我想我最初的想法是对的。拥有用户 ID 和键/值是有意义的,因为它保存了查询。你认为这对于群聊来说是可扩展的吗?其他的想法是,你怎么知道用户 ID 的顺序?
    • 关于订单 - 排序救援。关于扩展到群聊 - 我从来不需要这样的功能。 YAGNI + 总是值得问“最坏的情况会发生什么”:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    相关资源
    最近更新 更多