Firebase Flutter中监听多个ChatRoom下chats子集合的方案咨询
性能开销问题
- 你当前的实现方式确实会带来较高的设备性能开销。单客户端同时维持500个实时监听器,每个监听器都需要独立维持和服务端的长连接通道,会占用不小的客户端内存,还会额外增加设备电量消耗,低端设备甚至可能出现应用卡顿、后台进程被系统强制回收的问题。另外大部分云原生数据库(比如Firestore)默认单客户端最多仅支持同时开启100个实时监听器,超过配额后要么监听器启动失败,要么会自动挤掉之前的旧监听器,根本跑不起来500个并行监听的逻辑。
数据库读量问题
- 读量本身不会超出合理范围:实时监听器只有在首次初始化拉取数据、以及后续数据发生变更时才会产生读计数。如果每个
chats子集合你只监听最新1条消息,首次初始化会产生500次读,后续每收到1条新消息产生1次读,这个读量并不算高。但对比优化后的方案,这个读量还是偏冗余的。
最优实现方案
推荐你调整数据结构后用单监听器实现,成本最低效果最好:
- 新增根级
chats集合,每个消息文档携带chatRoomId、发送者ID、接收者ID、participants(存两个参与者ID的数组)、消息内容、发送时间等字段 - 给
participants和发送时间字段建复合索引,用户侧直接发起查询where("participants", "array-contains", "当前用户ID"),按发送时间倒序排序,加limit限制拉取最近N条消息,只需要1个监听器就能实现所有联系人新消息的实时监听 - 如果不想改动现有结构,也可以给所有
chats子集合的消息文档新增participants数组字段,开启集合组查询监听所有chats子集合中包含当前用户ID的消息,同样只需要1个监听器就能完成需求,注意要提前配置好集合组查询的数据库权限规则。
这种方案只需要维持1个长连接,性能开销可以忽略不计,首次初始化读次数就是你limit设置的条数,远低于之前的500次,后续新消息的读计数和原有方案一致。
内容的提问来源于stack exchange,提问作者Fiaz Ali
相关产品推荐
相关产品推荐

