Firestore结构咨询:批量条件推送通知的数据库结构是否合理?
问题:Firestore结构设计适配批量推送通知的条件查询
我使用Firestore作为NoSQL数据库,正在设计可支持条件查询以发送批量推送通知的最优结构,目前遇到了困扰。
原数据结构
采用collection/doc/subcollection/doc的层级:
users/ <-- 根集合 [userId] { push token } items/ <-- 子集合 [itemId] { item data }
我把用户的push token存在users/[userId]层级,用户的实际数据存在其子集合中,但这个结构无法跨所有用户基于子集合数据进行查询。
改进后的结构方案
将子集合移为独立根集合,每个文档包含所属users/[userId]的引用:
users/ [userId] { push token } items/ [itemId] { item data, [userId] }
计划在云函数中执行以下逻辑:
- 在
users根集合存储push token; - 获取所有存储了push token的用户文档;
- 遍历这些用户ID,条件性获取关联的item数据。
请问该结构是否适合筛选需要发送推送通知的用户?
这个改进后的结构完全适合筛选需要推送的用户,还可以通过细节优化进一步提升效率:
核心优势
- 根集合
items支持直接全局条件查询,能快速筛选出符合推送触发条件的条目,再关联对应的用户ID,彻底解决了原结构中子集合无法跨用户查询的问题。 users集合独立维护push token,和业务数据解耦,查询token时更高效,也方便单独管理用户的推送状态。
- 根集合
优化建议
- 调整查询逻辑顺序:先根据推送条件查询
items集合,得到符合条件的所有userId,再批量查询这些userId对应的users文档获取push token。这种方式能避免全量遍历用户,减少无效的数据库请求。 - 在
items集合的userId字段上建立索引,确保关联查询的性能。 - 如果推送条件涉及用户属性+item属性的组合,可以在
items文档中冗余部分关键用户属性(比如用户的订阅标签),这样无需关联users就能完成筛选,进一步提升查询效率。
- 调整查询逻辑顺序:先根据推送条件查询
注意事项
- 要处理
users文档不存在的情况(比如用户已删除但items文档未清理),避免无效的推送请求。 - 批量查询时使用Firestore的
getAll()方法,比循环单查更节省资源和时间。
- 要处理
内容的提问来源于stack exchange,提问作者Dan Page
相关产品推荐
相关产品推荐

