Firestore规则if..else

时间:2018-06-06 00:21:56

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

我刚刚开始了解Firestore规则,我的脑袋正在快速扩张。

我正在尝试研究如何将规则应用于一个集合,将另一个规则应用于所有其他集合及其子集合。

所以我从Firestore附带的默认规则开始:

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

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

允许对所有集合及其文档进行读写访问。

但是假设我想将规则应用于一个集合中的文档,并保留所有其他集合的默认规则。以下内容不起作用:

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

      match /suppliers/{supplier} {
        allow create: if !exists(/databases/$(database)/documents/supplierABNs/1260)
}

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


 }
}

因为第二条规则会覆盖第一条规则。

有没有办法做我想做的事情?

3 个答案:

答案 0 :(得分:1)

这里的根本问题是,当您有多个match语句时,如果任何match语句返回true,则将允许读/写。可以在此处的文档中找到对此的参考...

https://firebase.google.com/docs/firestore/security/rules-structure#overlapping_match_statements

要实现您想做的事情,您需要从规则中排除匹配所有文档的特定路径。这可以通过添加检查路径的第一部分是否与您排除的路径不匹配来完成。

var secretWords = ["batman", "donkey kong", "ninja", "programming"];
var chosenWord = secretWords[Math.floor(Math.random()*secretWords.length)];
var guesses = 8;
var letters = chosenWord.length

alert(chosenWord);

var guess = prompt("GUESS A LETTER");
var guessLowerCase = guess.toLowerCase();
var isGuessedLetterInWord = chosenWord.includes(guessLowerCase);

if (isGuessedLetterInWord) {
  alert('nice');
} else {
  alert('wrong');
}

答案 1 :(得分:0)

我了解您要对一个集合中的文档应用规则,并为所有其他集合保留默认规则。有一种方法可以做您想做的事情,而您不会喜欢它。

您必须为所有其他集合明确指定默认规则。

这是一个样本。

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

    //Rule for Suppliers collection
    match /suppliers/{supplier} {
        allow create: if !exists(/databases/$(database)/documents/supplierABNs/1260)
    }

    //Rule for Changelog collection allowing complete access
    match /Changelog/{id} {
        allow read: if true;
        allow write: if true;
    }

    //Rule for Vendors collection allowing complete access
    match /Vendors/{id} {
        allow read: if true;
        allow write: if true;
    }

  }
}

注意:Firestore规则不支持if语句。但是您可以使用AND和OR条件作为一种模拟方法来解决此问题。

答案 2 :(得分:-1)

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

    match /suppliers/{supplier} {
      allow create: if isValidSupplier()
    }

    function isValidSupplier() {
        return resource.data.supplierABNs == '1260'
    }

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

resource.data包含现有文档中的值。