Firestore模拟器执行单个操作时触发多请求的行为是否正常?
Firestore模拟器执行单个操作时触发多请求的行为是否正常?
嘿,我来帮你梳理下这个问题~
先结合你给出的代码和观察到的现象,明确告诉你:这种单个写操作触发多个请求的情况,在Firestore模拟器里是完全正常的,大概率不是bug,也不一定是你的安全规则写错了,下面给你拆解背后的原因:
1. 模拟器的内部交互逻辑
你执行setDoc时看到3个请求,执行updateDoc时看到2个请求,这是Firestore客户端和模拟器交互的常规流程:
- 对于你这段
setDoc代码:
模拟器会拆分出3个请求,分别对应「权限规则预检查」、「实际写入/覆盖文档」、「文档状态确认/索引同步」这几个环节。const docRef = doc(this.fs, `users/${userUid}/items`, item.id); return from(setDoc(docRef, item)).pipe(... - 对于你这段
updateDoc代码:
因为是更新现有文档,不需要额外的文档存在性确认步骤,所以会拆分成「权限规则预检查」+「实际更新文档」2个请求。const docRef = doc(this.fs, `users/${userUid}/items`, update.id); return from(updateDoc(docRef, update)).pipe(...
你观察到的请求数量完全符合这个正常流程。
2. 安全规则的影响
你的安全规则里用到了request.resource.data.diff()这类需要对比新旧数据的方法(比如onlyAllowedKeysChanged和atLeastOneOfKeysChanged):
function isLoggedInUser(request) { return request.auth != null && request.auth.token.email_verified; } function isUsersOwnAccount(request, userId) { return request.auth.uid == userId; } function onlyAllowedKeysChanged(request, resource) { return request.resource.data.diff(resource.data).affectedKeys().hasOnly([...]) } function atLeastOneOfKeysChanged(request, resource) { return request.resource.data.diff(resource.data).affectedKeys().hasAny([...]) } match /users/{userId}/items/{itemId} { allow create: if isLoggedInUser(request) && isUsersOwnAccount(request, userId) && isValidItem(request.resource.data); allow update: if isLoggedInUser(request) && isUsersOwnAccount(request, userId) && atLeastOneOfKeysChanged(request, resource) && onlyAllowedKeysChanged(request, resource); }
模拟器在验证这些规则时,确实会额外发送请求来获取现有文档的资源数据(比如update操作里需要用到resource.data做对比),但这是规则验证的正常流程,不是你的规则配置错误。只要你把hasOnly([...])和hasAny([...])里的[...]替换成了实际允许修改的键列表,你的规则逻辑就是没问题的。
3. 需要警惕bug的情况
如果出现以下情况,才需要考虑是否是模拟器bug或者配置问题:
- 多请求导致了重复写入/更新(比如同一个文档被创建了多次)
- 模拟器返回权限错误,但实际操作却成功了(反之亦然)
- 请求数量远超过3个/2个,且持续增加
如果只是多请求但最终操作结果正确,那完全不用担心~
备注:内容来源于stack exchange,提问作者pax
相关产品推荐
相关产品推荐

