[英]Run Loop in firestore rules
It is requirement to run loops in data validation.在数据验证中运行循环是必需的。 In my case I have document with schema:
就我而言,我有带有架构的文档:
interface SomeDoc {
// ...other props
"prop-with-map": { [key: string]: number };
}
still there is no way to validate SomeDoc["prop-with-map"]
仍然没有办法验证
SomeDoc["prop-with-map"]
I let user create this document, then they can't update so need to check schema in firestore-rules.我让用户创建此文档,然后他们无法更新,因此需要检查 firestore-rules 中的架构。 Without loops or schema check support in rules I have to make background function.
如果规则中没有循环或模式检查支持,我必须制作背景 function。
OR或者
I know there can't be more then 5 fields in SomeDoc["prop-with-map"]
.我知道
SomeDoc["prop-with-map"]
中不能有超过 5 个字段。 So I can check them one by one.所以我可以一一检查。 Or create js function that generates code firestore-rule-function that checks in arr one by one.
或者创建 js function 生成代码 firestore-rule-function 来一一检查 arr。
SOLUTION解决方案
/**
* @param {string} functionName what function name you would like.
* @param {string} validate what is validator function name.
* @param {number} iteration max iteration before exiting loop.
* @return {string} function code used in firestore rules
*/
function generateFirestoreLoopForList(functionName, validate, iteration) {
let func = `function ${functionName}(arr) {\n return arr.size() == 0 ? true : ${validate}(arr[0])`;
for (let i = 1; i <= iteration; i++) {
let addAtIndex = func.length - i + 1;
func =
func.substring(0, addAtIndex) +
`&& (arr.size() == ${i} ? true : ${validate}(arr[${i}]))` +
func.substring(addAtIndex);
}
func += "\n }";
console.log(func);
return func;
}
then your rules can go like那么你的规则可以像 go
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /TEST/TEST {
allow create: if checkOtherProps() && hasAllOdd(request.resource.data["prop-with-map"].values());
function checkOtherProps() {
return // validate props and return accordingly;
}
function isInt(x) {
return x is int;
}
// outuput of generateFirestoreLoopForList("hasAllInts", "isInt", 5);
function hasAllInts(arr) {
return arr.size() == 0 ? true : isInt(arr[0])&& (arr.size() == 1 ? true : isInt(arr[1])&& (arr.size() == 2 ? true : isInt(arr[2])&& (arr.size() == 3 ? true : isInt(arr[3])&& (arr.size() == 4 ? true : isInt(arr[4])&& (arr.size() == 5 ? true : isInt(arr[5]))))));
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.