我正在尝试编写一些Firestore安全规则,这些规则仅允许用户写入其文档中的某些字段(例如电子邮件,性别,preferredName,地址)。
我编写了以下写入规则,以限制对特定字段的访问:
match /databases/{database}/documents {
match /users/{userId} {
allow read: if userIsAuthenticated()
&& userIsAccessingTheirData(userId);
// Users can always write to specific fields
allow write: if userIsAuthenticated()
&& userIsAccessingTheirData(userId)
&& request.resource.data.keys().hasOnly(["preferredName","gender", "email", "address"]);
该规则适用于在代码中调用 userDoc.set 的情况,但是当我们调用 userDoc.update 时不起作用。
使用Firestore规则仿真器,我可以看到,当我们调用“设置”时,request.resource.data.keys()
仅包含在调用中传递的字段,但是当我调用“更新”时,文档的所有字段在密钥集合中:-(使其无法过滤。
是否有一种方法可以编写一条安全规则来限制像上述那样适用于set和update的字段?
答案 0 :(得分:1)
request.resource
变量表示文档,它在操作成功后会存在( if 当然会成功)。因此request.resource
不会只包含正在更新的字段,还包含现有文档中的其他值。
始终可以通过将request.resource.data.fieldname
与resource.data.fieldname
进行比较来检查字段是否正在更新。
但是最近,安全规则引入了新的affectedKeys()
函数,该函数仅显示增量:
// This rule only allows updates where "a" is the only field affected
allow update: if request.resource.data.diff(resource.data).affectedKeys().hasOnly(["a"]);
答案 1 :(得分:0)
您可以使用request.resource.data。{field}
访问文档字段例如,如果您想限制更新dob:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /users/{user} {
allow update: if request.resource.data.dob == resource.data.dob;
}
}
}
这意味着只要dob不变,就可以更新文档。