【发布时间】:2021-07-17 05:13:16
【问题描述】:
我的应用中有一个群聊功能,其消息节点的结构如下所示。目前,它不使用扇出技术。它只列出组名下的所有消息,例如“组1”
groups: {
group1: {
-MEt4K5xhsYL33anhXpP: {
fromUid: "diidssm......."
userImage: "https://firebasestorage..."
text: "hello"
date: 1617919946
emojis: {
"heart": 2
"like": 1
}
}
-MEt8BLP2yMEUMPbG2zV: {
...
}
-MF-Grpl8Jchxpbn2mxH: {
...
}
-MF-OUjWXsFh7lBPosMf: {
...
}
}
}
我首先观察最近的 40 条消息,然后观察是否添加了新的孩子
ref = Database.database().reference().child("groups").child("group1")
ref.queryLimited(toLast: 40).observe(.childAdded, with: { (snapshot) in
...
//add to messages array to load collection view
//for each message observe emojis and update emojis to reflect changes e.g. +1 like
ref.child("emojis").observe(.value, with: { (snapshot) in
...
})
})
每次用户向上滚动时,我都会使用最后日期(以及安全规则中的日期索引)再加载 40 条消息(并观察每个消息节点下的表情符号子节点)
ref.queryOrdered(byChild: "date").queryEnding(beforeValue: prevdate, childKey: messageId).queryLimited(toLast: 40).observeSingleEvent(of: .value, with: { (snapshot) in
我了解扇出技术用于在每次同步时获取更少的信息。如果我将侦听器附加到 groups/groupname/ 以获取该组的所有消息的列表,我还将询问该节点下每条消息的所有信息。使用扇出方法,我还可以使用来自另一个节点的消息的键来询问最近 40 条消息的消息信息,以及接下来的 40 条消息。
allGroups: {
group1: {
-MEt4K5xhsYL33anhXpP: 1
-MEt8BLP2yMEUMPbG2zV: 1
-MF-Grpl8Jchxpbn2mxH: 1
-MF-OUjWXsFh7lBPosMf: 1
}
}
但是,如果我使用的是 queryLimited(toLast: 40),那么扇出方法是否有益甚至是必要的?这不是解决了“我还会询问该节点下的每条消息的所有信息”的问题吗?
在检查新消息方面,我只是在上面的第一个代码中使用 .childAdded 进行检查(ref.queryLimited(toLast: 40).observe(.childAdded))。根据下面的帖子,queryLimited(toLast: 40) 将同步最后 40 个子节点,并继续同步那些(在添加新节点时删除以前的节点)。
Some questions about keepSynced(true) on a limited query reference
我假设 group1 有 1000 条消息,通过这种方法,我只阅读我需要的 40 条最新消息和接下来的 40 条每个滚动条,因此忽略其他数百条消息。那我为什么要使用扇出技术呢?可能是我不了解有关有限查询的基本知识。
附带问题:我是否应该在每个消息节点下包含对个人资料图像的引用?在云存储和实时数据库存储方面这样做是不是很糟糕?理想情况下会有数百个群聊。
【问题讨论】:
-
扇出数据可以有多种形式。当您说“扇出技术”时,您能否编辑您的问题以显示您想到的 JSON?
-
当然。刚刚添加。
-
我不确定我是否理解这种新数据结构与您问题顶部的数据结构之间的关系。如果您随后以无法通过查询处理的方式加载特定组的数据,而不是其他组的数据,那么拥有这样的组 ID 列表是一个好主意。由于查询对您有用,我不会立即看到对解构数据的需求,但这可能是因为我现在不了解您的所有用例。
-
成千上万的人从哪里来 - 如果有数千个帖子,那么这些帖子中有成千上万的表情符号观察者。如果 emoji 节点是独立的,那么同一个任务需要一个观察者并加载更少的数据;所以这只是一个设计选择。将参考存储到用户节点中的图像需要额外的读取,因为帖子被读取,然后用户节点从存储中获取图片。另一方面,将 ref 保留在帖子中会减少阅读量,但如果图片发生变化,您必须在每篇帖子中更新它。我会投票给前一个。
-
ref.queryLimited(toLast: 40)有点不清楚,直到您将大脑围绕它。这实际上是在说“无论查询是什么,限制为最后 40 个”;它不会查询所有内容以获取最后 40 个。因此,如果 40 个“位于顶部”或 40 个“位于末尾”,则性能“相同”;它不是“查看”其他顶级节点。读取性能不会受到显着影响,而且...... Firebase 速度非常快,因此实际上很难制作影响读取性能的东西。 @FrankvanPuffelen 可能想纠正/更新我,但这是我们的测试显示的。
标签: swift firebase performance firebase-realtime-database