如何使用Firestore的安全规则验证数组值?

时间:2018-08-15 10:48:31

标签: firebase google-cloud-firestore firebase-security-rules

我有一个创建以下JSON结构的表单。

{  
   "reviewed":false,
   "title":"Just a title",
   "user":"UYV9TRKXfNW1NeCyFyfjZfagJ8B",
   "items":[  
      {  
         "age":"33",
         "experience":"Newcomer",
         "image":"https://image-url",
         "job":"Nerd",
         "name":"Testname",
         "party":"AAA",
         "type":"person"
      },
      {  
         "age":"33",
         "experience":"Newcomer",
         "image":"https://image-url",
         "job":"Informatiker",
         "name":"Testname",
         "party":"AAA",
         "type":"person"
      }
   ]
}

如何使用Firestore的安全规则检查“项目”的值?有没有办法遍历/迭代数组?

2 个答案:

答案 0 :(得分:3)

为了完整性:到目前为止,这是我的解决方案。我按照链接答案中所述的方式进行了操作。可能的商品数量限制为10,因此我们可以避免动态循环。

service cloud.firestore {
  match /databases/{database}/documents {
    match /events/{event} {

      function isAuthed() {
        return request.auth.uid != null
            && request.auth.uid == request.resource.data.user
            && request.auth.token.email_verified == true;
      }

      function isReviewed() {
        return request.resource.data.reviewed == false
            || request.resource.data.reviewed == "false"
      }

      function isValidTitle() {
        return isValidStringInput(request.resource.data.title, 200);
      }

      function items() {
        return request.resource.data.items;
      }

      function isValidPerson(item) {
        return items()[item].keys().hasAll(['image','type','name','job','age','party','experience'])
                && isValidStringInput(items()[item].image, 100)
                && isValidStringInput(items()[item].type, 10)
                && isValidStringInput(items()[item].name, 50)
                && isValidStringInput(items()[item].job, 50)
                && isValidStringInput(items()[item].party, 50)
                && isValidStringInput(items()[item].experience, 50)
                && isValidNumber(items()[item].age);
      }

      function isValidParty(item) {
        return items()[item].keys().hasAll(['image','type','name','orientation','experience','promi'])
                && isValidStringInput(items()[item].image, 100)
                && isValidStringInput(items()[item].type, 10)
                && isValidStringInput(items()[item].name, 50)
                && isValidStringInput(items()[item].orientation, 50)
                && isValidStringInput(items()[item].experience, 50)
                && isValidStringInput(items()[item].promi, 50);
      }

      function isValidItem(item) {
        return isValidPerson(item)
            || isValidParty(item);
      }

      function isValidStringInput(input, maxSize) {
        return input is string
            && input.size() > 0
            && input.size() <= maxSize;
      }

      function isValidNumber(input) {
        return input is int
            || input.matches('^[0-9]+$');
      }

        // One can READ
            // always ...
        allow read: if true;

      // One can WRITE, when ...
        // writer is logged in
        // uid in event is same as uid of writer
        // writer has email confirmed
        // reviewed is initial set to false
        // form/user input is ok
      allow write, update:
        if isAuthed()
        && isReviewed()
        && isValidTitle()
        && items().size() >= 1
        && items().size() <= 10
        && isValidItem(0)
        && (items().size() < 2 || isValidItem(1))
        && (items().size() < 3 || isValidItem(2))
        && (items().size() < 4 || isValidItem(3))
        && (items().size() < 5 || isValidItem(4))
        && (items().size() < 6 || isValidItem(5))
        && (items().size() < 7 || isValidItem(6))
        && (items().size() < 8 || isValidItem(7))
        && (items().size() < 9 || isValidItem(8))
        && (items().size() < 10 || isValidItem(9));
    }
  }
}

答案 1 :(得分:0)

据我所知。您仍然无法在Firestore安全规则中使用循环,并且链接的答案仍然有效,该示例仍然有效,并说明了如何使用functions进行验证。如果数组增加,这可能变得不可用,最好为项目选择其他数据结构,例如自己的集合。

干杯, 拉斯