Firestore带limit(1)的查询监听器新增文档时不触发怎么解决?
Firestore 带limit的新增文档监听不触发解决方案
问题原因
你遇到的触发失效是Firestore快照监听器的默认行为导致的:默认配置下,只有服务端返回的文档数据变更才会触发回调,本地写入产生的临时变更、以及未改变现有limit结果集结构的变更可能不会主动推送。你移除limit后能触发,是因为此时所有符合条件的文档变更都会被纳入监听范围,但是确实会带来不必要的历史文档读取开销。
可选解决方案
方案一:仅监听新增文档(最低开销)
如果不需要获取历史存量数据,仅需要监听监听启动后新创建的符合条件的文档,可通过增加时间过滤条件实现,开销仅为每次新增文档1次读取,无历史数据拉取成本:
// 记录监听器启动的时间点 let listenerStartTimestamp = Timestamp() firestore .collection("users") .document("123") .collection("images") .whereField("postId", isEqualTo: "123") // 仅筛选创建时间晚于监听器启动时间的文档,也就是新增文档 .whereField("createdAt", isGreaterThan: listenerStartTimestamp) .order(by: "createdAt", descending: true) .limit(to: 1) // 开启元数据变更监听,保证本地写入也能触发回调 .addSnapshotListener(includeMetadataChanges: true) { [weak self] snapshot, error in guard let snapshot = snapshot, error == nil else { return } // 只处理新增类型的文档变更 snapshot.documentChanges.forEach { change in if change.type == .added { print(change.document) // 你的业务逻辑 } } }
方案二:保留历史最新1条监听
如果你需要同时拿到当前已存在的最新1条文档,后续新增更新的文档也能触发回调,只需要给监听器增加includeMetadataChanges: true参数即可:
firestore .collection("users") .document("123") .collection("images") .whereField("postId", isEqualTo: "123") .order(by: "createdAt", descending: true) .limit(to: 1) .addSnapshotListener(includeMetadataChanges: true) { [weak self] snapshot, error in guard let imageDocument = snapshot?.documents.first else { return } print(imageDocument) // 你的业务逻辑 }
排查项
如果上述方案仍未生效,可临时关闭Firestore本地持久化验证是否是缓存导致的异常,该操作仅用于排查,不建议生产环境关闭:
Firestore.firestore().disablePersistence { error in if let error = error { print("关闭持久化失败:\(error)") } }
内容的提问来源于stack exchange,提问作者Vitor
相关产品推荐
相关产品推荐

