shm*_*les 3 firebase-security google-cloud-firestore
document structure:
{
[id 1] {
field1: "value",
field2: "value",
field3: "value"
}
[id 2] {
field1: "value",
field2: "value",
field3: "value"
}
[id 3] {
field1: "value",
field2: "value",
field3: "value"
}
}
Run Code Online (Sandbox Code Playgroud)
the map ids reference documents and cannot be hardcoded, but field names (field1, field2...), are the same in each map
is there a way to check that only 1 field in any 1 map is changed, and allow write if those conditions are met?
为了将所有验证逻辑保留在 Firestore 中,您可以使用的一种技巧是为您的写入请求添加冗余。例如,您可以从客户端发送以下数据:
firestore.collection('A').doc('B').update({
'your_id_here': {
field1: 'my new value',
// keep old data, since we are updating a nested object
field2: 'original value',
field3: 'original value'
},
// this is the redundancy component
meta: { id: 'your_id_here' }
});
Run Code Online (Sandbox Code Playgroud)
然后,在 Firestore 规则中,您可以按如下方式定义写入规则:
function valid() {
// grab ID from "redundant" part of the request
let metaID = request.resource.data.meta.id;
// grab changed keys in the root of the document
let rootAftectedKeys = request.resource.data.diff(resource.data).affectedKeys();
// validate root keys; need to include "meta", since it is now also part of the object
let rootChangesGood = rootAffectedKeys.hasOnly([metaID, 'meta']);
// grab the nested object in question
let nestedObjectChanges = request.resource.data[metaID].diff(resource.data[metaID]).affectedKeys();
// check there was only one affected key
let nestedObjectChangesGood = nestedObjectChanges.size() == 1;
return rootChangesGood && nestedObjectChangesGood;
}
allow write: if valid();
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用metaID变量来动态访问对象的键。
这种方法的优点是 (1) 所有验证逻辑都在 Firebase 中,(2) 它比执行云函数要快得多(因为您只是直接与 Firestore 通信)。
但是,这种方法的缺点是您将让这个meta对象漂浮在每个人身上都可以看到。最重要的是,我将添加更多验证以确保meta对象本身仅具有正确格式的必需数据。我强烈建议彻底测试所有可能的场景。
| 归档时间: |
|
| 查看次数: |
384 次 |
| 最近记录: |