无法在 Firebase Firestore 安全规则中使用逻辑 OR 运算符 - 条件始终评估为“false”

wub*_*ube 5 firebase firebase-security google-cloud-firestore

/companies/{company}如果登录用户是经理记录不存在,我想允许写入。

我有以下安全规则:

service cloud.firestore {
  match /databases/{database}/documents {
    function isManager() {
      return get(/databases/$(database)/documents/managers/$(request.auth.uid)).data.id == request.auth.uid;
    }

    function companyExists(company) {
      return exists(/databases/$(database)/documents/companies/$(company));
    }

    match /{document=**} {
      allow read, write: if false;
    }

    match /companies/{company} {
      allow read: if resource.data.isActive == true || isManager();
      allow write: if !companyExists(company) || isManager();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

以下行有问题:

allow write: if !companyExists(company) || isManager();
Run Code Online (Sandbox Code Playgroud)

false即使!companyExists(company)函数计算结果为 ,此条件也始终计算为true

我确信companyExists(company)isManager()函数可以按预期工作,因为我已经分别测试了它们。

例如,如果我使用以下规则:

allow write: if !companyExists(company);
Run Code Online (Sandbox Code Playgroud)

然后,表达式的计算结果true是公司记录不存在。与isManager()功能相同。true如果集合中存在登录用户的 ID,则返回managers。仅当在两个函数之间使用运算符时才会出现该问题||

Ric*_*nia 0

似乎您希望允许每个人创建公司,但只有经理才能编辑它们。这可以通过更简单的方式实现:

match /companies/{company} {
  allow read: if resource.data.isActive == true || isManager();
  allow create;
  allow update, delete: if isManager();
}
Run Code Online (Sandbox Code Playgroud)

它还会更便宜,因为您不需要执行 get 请求来检查它是否存在。

此外,还可以使用自定义声明而不是文档来重写 isManager 的逻辑,这样您还可以保存另一次读取。这超出了这个问题的范围,但如果您需要更多详细信息,请发表评论。