0
votes

I have an app using Cloud Firestore. I'm trying to secure my database with Firebase security rules and have been struggling with receiving a document that I'm querying through a collection group query.

  • Here is my security rule that is passing the emulator, but not inside my web app.
match /{path=**}/groups/{groupId} {
  allow read: if resource.data.id == resource.id;
}
  • If I hardcode my rule to this:
match /{path=**}/groups/{groupId} {
  allow read: if resource.data.id == "1" <--- hard coding the value to match my DB, this works;
}
  • This is how I query for the group:
this.db
  .collectionGroup('groups')
  .where('id', '==', id)
  .get()
  .then(snapshot => { ... });

Screenshot: enter image description here

1
Hi @scarsam, I am not completely sure what your use case is, but it is not clear why you have a document 1, which contains an id field 1. May be redundant. I believe what is happening with your hardcore rule is expected since the only instance, which this rule will work is only when the value is "1". If your document 2 had an id field, which equals 2, then it will only work for hardcoded value 2 and not 1, and so forth. Hope this helps. - sllopis

1 Answers

0
votes

I wouldn't expect that first rule to work in any situation because it's attempting to filter documents based on their contents. Security rules are not filters. If it works in the console simulator, that might be a bug in the simulator. Also, bear in mind that the simulator does not simulate queries, it just tests document gets.

The second rule works because the client query exactly matches the rules. They are both requiring a document id property of "1". Since the client is specifying the filter, and the filter matches the rule, it's OK.

It's not entirely clear to me what your first rule is supposed to be allowing or rejecting. It looks like you want it to only allow documents whose ID property is the same as its actual document ID. But since the client is not actually capable of expressing that filter condition, the rule is simply rejecting the query every time.