Firestore安全规则自定义函数调试:解决“Property resource is undefined on object”错误
解决Cloud Firestore安全规则中
resource is undefined错误及所有者校验问题 首先,咱们拆解你遇到的两个核心问题:resource未定义的报错,以及如何正确测试所有者校验规则。
一、为什么会触发Property resource is undefined on object错误?
这个报错的核心原因很明确:当Firestore找不到你要操作的现有文档时,resource对象就会不存在。
你设置的是allow update规则,resource代表的是数据库中已存在的目标文档。如果在模拟器测试时,你没有指定一个真实存在的子集合文档路径,Firestore无法定位到现有文档,自然就会抛出resource未定义的错误——这正是官方建议里“输入实际存在的文档路径”的意义所在。
二、四个自定义函数的逻辑分析
结合你的需求(校验请求用户是内容所有者),咱们逐个梳理:
belongsToRequestor1():逻辑是正确的——检查现有文档的userId是否等于当前请求用户的uid。但前提是你测试时必须指定一个已存在的、包含userId字段的文档路径。belongsToRequestor2():逻辑错误,因为你明确说明子集合文档没有uid字段,用这个永远不会匹配成功。belongsToRequestor3():逻辑偏离需求——它检查的是更新后文档的userId是否等于用户uid,而不是现有文档的。这适合用来限制用户不能修改userId字段,但不是校验所有者身份。belongsToRequestor4():既逻辑错误(文档无uid字段),又偏离需求(检查的是更新后的数据)。
所以,正确的所有者校验函数应该是belongsToRequestor1(),但需要配合正确的测试方式。
三、如何正确在模拟器中测试规则?
因为你的子集合文档ID是Firebase自动生成的,按以下步骤操作即可:
- 打开Firestore控制台,找到你用来测试的
reviews子集合文档,复制它的完整路径,格式类似:/properties/abc123/reviews/xyz789(其中abc123是父集合properties的文档ID,xyz789是自动生成的reviews文档ID)。 - 打开规则模拟器:
- 操作类型选择Update;
- 文档路径粘贴你刚才复制的完整路径;
- 在“认证”区域,勾选“已认证”,并填写该文档
userId字段对应的uid值; - 在“请求数据”里填写你要更新的字段(比如
{"comment": "Updated comment"});
- 点击“运行”,此时规则会正确读取
resource.data.userId,不会再抛出未定义错误。
四、修正后的规则示例
这里给你整理了更健壮的规则结构,补充了未认证用户的判断,避免额外报错:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 正确的所有者校验函数:检查现有文档的userId是否等于当前用户uid function belongsToRequestor() { return request.auth != null && request.auth.uid == resource.data.userId; } match /properties/{propertyId}/reviews/{reviewId} { // 允许更新:用户已认证 + 是文档所有者 allow update: if belongsToRequestor(); // 可选:限制创建时只能设置自己的userId,避免乱填 allow create: if request.auth != null && request.resource.data.userId == request.auth.uid; } } }
内容的提问来源于stack exchange,提问作者Mark Gavagan
相关产品推荐
相关产品推荐

