以下是我的Firebase实时数据库的架构:
聊天节点
- 聊天
- 聊天标识
- 聊天标识
- 管理员用户标识
- 聊天主题
- 聊天图标网址
- 聊天创建日期
- 最后更新
- 聊天标识
用户聊天节点
- user_chats
- 用户标识
- 聊天ID:真
- 用户标识
我想做什么:
我想做的是在我的应用程序ChatListFragment
中显示用户订阅的所有聊天的列表,并观察其更改,例如,添加新聊天,删除任何聊天,chatSubject
更改,chatIconUrl
,lastUpdated
等。
我做了什么:
由于我已经对数据进行了非规范化,因此第一步是检索给定用户订阅的聊天ID列表,我可以很容易地实现如下:
FirebaseDatabase.getInstance().getReference("user_chats").child(userId).addValueEventListener()
下一个任务是根据上面检索到的每个聊天 ID 从节点chats
获取完整的聊天数据。 我知道我无法编写查询来实现此目的,因为检索到的聊天 ID 是数百或数千个总聊天 ID 中的随机子集。 因此,我循环遍历检索到的聊天 ID 并为每个聊天 ID 触发查询,如下所示,并在ArrayList
中逐个收集检索到的Chat
(映射到节点chats
字段中字段的 POJO(对象:
FirebaseDatabase.getInstance().getReference("chats").child(chatId).addValueEventListener()
在这里,我必须通过将ArrayList<Chat>
的大小与从节点检索到的聊天 ID 的大小相匹配来确保user_chats
完整性。当两个尺寸相等时,我向ListAdapter
提供ArrayList<Chat>
。
但是,除了上述内容之外,我还必须处理以下问题:
- 查看为什么调用附加到每个聊天 ID 的侦听器的 onDataChanged((:以提供新的聊天快照或报告已提供的聊天快照中的更改。
- 删除与给定用户不再订阅的聊天 ID 关联的侦听器。
当我尝试使用LiveData
在ViewModel
中完成所有操作时,这变得更加复杂。
以下是我的问题:
我真的必须经历这样的麻烦来编译用户订阅的聊天列表吗?这应该是我的应用程序的第一个屏幕,我碰巧无法通过它。
是否有标准/更好的方法可以在相同的数据结构下实现我的目标?
我是否需要进一步更改数据结构才能实现目标?我的想法是通过添加
chats
节点具有的相同字段来扩展user_chats
节点。这似乎很奇怪,因为首先,如果聊天中有 500 个成员,user_chats
节点中会有 500 个聊天副本,其次,如果数据有任何更新,我将更新chats
节点中的聊天信息,然后user_chats
节点中的所有 500 个副本。当我们考虑lastUpdated
字段的更新频率时,这将是荒谬的。
任何帮助将不胜感激!
知道所有查询何时完成。
一种常见的方法是计算它们。由于您知道/user_chats/$uid
下有多少个聊天ID,因此您知道必须从/chats
下加载多少个节点。每次获得其中一个节点的第一个结果时,都会递增一个计数器。当您加载的聊天数量等于用户的聊天 ID 数量时,您就完成了。