简体   繁体   English

在 Firestore 规则中运行循环

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM