分层云Firestore规则中的变量

时间:2018-09-26 16:18:23

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

我在Cloud Firestore中设置了以下规则。结构为: /users/{userId}/years/{year}/**。如果该年份设置了year标志,我想拒绝对closed文档及其子集合及其文档进行任何写操作。

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

    match /users/{userId} {
        allow read, update: ...;
        allow delete: ....; 
        allow create: ...

        match /years/{year} {
            allow read, create: ...;
            allow delete: ...;          
            allow update: if request.auth.uid == userId && !resource.data.closed

            match /{document=**}  {
                allow read: ...;
                allow write: if get(/databases/$(database)/documents/users/$(userId)/years/$(year)).data.closed == false
                    && request.auth.uid == userId;      
            }
        }       
    }
  }
}

年度级别的规则似乎有效。但在此之下,无论标记状态如何,get调用中的所有请求都会失败(在模拟器和应用程序中)。 Firestore文档中没有几个有关如何使用变量的示例-可以从上层继承变量吗?或者访问下面的任何文档时如何获得年份的标志字段?

[更新/解决方案]

经过大量的搜索并运行了更多的模拟之后,事实证明问题出在根本没有closed标志的情况下。在 undefined 中,firestore规则引擎似乎不如JS引擎具有优势。引发一个异常,等同于规则失败。必须检查该属性是否存在,然后测试该值。而且因为即使在函数中也无法使用局部变量,所以这意味着两个 get -s而不是一个...

match /years/{year} {
  match /{document=**}  {
   allow read: ...;
   allow write: if !(getYearData().keys().hasAll(['closed']) && getYearData().closed) && request.auth.uid == userId;      
   }

  function getYearData() {
    return get(/databases/$(database)/documents/users/$(userId)/years/$(year)).data;
  }
}

这个问题仍然需要更好的解决方案。

0 个答案:

没有答案