为什么Firestore查询中getDocuments()与getDocumentChanges()大小不一致?
Firestore查询getDocuments与getDocumentChanges计数不一致问题原因
问题背景
使用如下复合查询拉取Firestore数据时偶发IndexOutOfBoundException,经排查定位为getDocuments().size()与getDocumentChanges().size()返回值不一致:
.whereIn(gender_node, getInterestedIn()) .whereGreaterThanOrEqualTo(birthdate_year_node, getShowAgeMax() + 1) .whereLessThanOrEqualTo(birthdate_year_node, getShowAgeMin())
测试环境共有7条符合条件的文档,getDocuments().size()固定返回7,异常场景下getDocumentChanges().size()仅返回5。
核心原因
两个接口的设计定位本身就不存在一一对应的绑定关系:
getDocuments()返回当前查询命中的全量最终状态文档列表,会合并服务端返回结果、本地未同步的增删改操作后返回完整数据集getDocumentChanges()仅返回当前快照与上一次回调快照相比发生变更的文档记录,无变更的文档不会生成对应DocumentChange对象
偶现差异的触发场景
以下任意一种场景都会触发你观测到的7/5计数差异:
- 本地对2条符合查询条件的文档做了修改/删除操作,且变更后的文档依然符合查询过滤规则,不会触发
REMOVED类型的变更推送,此时全量列表合并本地变更后返回7条,变更记录仅包含服务端有更新的5条 - 开启了Firestore持久化缓存,首次冷启动查询拉取到全量7条文档,后续后台静默同步时只有5条文档有服务端更新,此时触发的增量快照回调中,全量列表返回合并后的7条,变更记录仅返回有更新的5条
- 该复合查询未配置对应复合索引,Firestore首次返回本地缓存的7条全量文档,后台补拉索引完成后的增量回调仅返回5条有效变更记录,导致两个接口计数不一致
修复方案
不要依赖两个接口的计数相等关系编写下标绑定的遍历逻辑:
- 如需处理全量文档,直接遍历
getDocuments()返回的列表即可 - 如需处理增量变更,单独遍历
getDocumentChanges()的每条记录,不要和全量文档列表的下标做绑定
内容的提问来源于stack exchange,提问作者murkr
相关产品推荐
相关产品推荐

