Firestore安全规则是否将写入限制为set和update?

时间:2020-03-26 01:27:12

标签: google-cloud-firestore firebase-security

我正在尝试编写一些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的字段?

2 个答案:

答案 0 :(得分:1)

request.resource变量表示文档,它在操作成功后会存在( if 当然会成功)。因此request.resource不会只包含正在更新的字段,还包含现有文档中的其他值。

始终可以通过将request.resource.data.fieldnameresource.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"]);

另请参阅release notes for Firebase security rules

答案 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不变,就可以更新文档。