Firestore安全性 - 仅允许已知字段

Fab*_*ger 11 firebase firebase-security google-cloud-firestore

我无法弄清楚如何在Firestore中正确设置'.validate'规则.基本上,我想允许用户文档包含我知道的字段:

user {
 name: "John"
 phone: "2342222"
 address: "5th Avenue"
}
Run Code Online (Sandbox Code Playgroud)

我不想要除上面3之外的任何其他领域(姓名,电话,地址).

这些字段不会同时保存.姓名电话将被保存,只有当用户想要编辑他的个人资料时才会保存地址.

我已经尝试过以下规则,但似乎不起作用:

allow read: if request.auth.uid == uid;
allow write: if request.auth.uid == uid && 
 request.resource.data.keys() in ["name", "phone", "address"]
Run Code Online (Sandbox Code Playgroud)

感谢帮助.

Mik*_*ald 12

您可以分开你的规则,包括不同的createupdate(以及delete)的逻辑:

// allows for creation with name and phone fields
allow create: if request.resource.data.size() == 2
              && request.resource.data.hasAll(['name', 'phone'])
              && request.resource.data.name is string
              && request.resource.data.phone is string;
// allows a single update adding the address field
// OR (||) in additional constraints
allow update: if request.resource.data.size() == resource.data.size() + 1
              && !('address' in resource.data)
              && request.resource.data.address is string;
Run Code Online (Sandbox Code Playgroud)


Dan*_*ath 5

您正在寻找size()hasOnly()方法。

allow write: if request.resource.data.size() == 3 
             && request.resource.data.keys().hasOnly(['name', 'phone', 'address'])
Run Code Online (Sandbox Code Playgroud)

使用size()可以确保字段的准确数量。结合使用它hasOnly()可以将其锁定到那些特定字段。

您可以在Cloud Firestore规则参考文档中阅读更多内容。

  • 嘿丹,谢谢你的回复。这不起作用,因为这些字段不会同时保存。姓名和电话将先保存,地址将稍后保存。因此,当我尝试仅保存“地址”时,规则将失败。 (2认同)

小智 5

要添加 Mike McDonald 的回答,要检查特定键,现在的表单是:

request.resource.data.keys().hasAll
Run Code Online (Sandbox Code Playgroud)

代替

request.resource.data.hasAll
Run Code Online (Sandbox Code Playgroud)

完整示例:

// allows for creation with name and phone fields
allow create: if request.resource.data.size() == 2
              && request.resource.data.keys().hasAll(['name', 'phone'])
              && request.resource.data.name is string
              && request.resource.data.phone is string;
// allows a single update adding the address field
// OR (||) in additional constraints
allow update: if request.resource.data.size() == resource.data.size() + 1
              && !('address' in resource.data)
              && request.resource.data.address is string;
Run Code Online (Sandbox Code Playgroud)

更多信息请访问:https : //firebase.google.com/docs/reference/rules/rules.Map