I'm facing a permission denied error when querying firestore, when I have introduced a rule. I have narrowed down my complex rule and filter to the below 2 examples of which one query works, and one doesn't. I do not understand what is wrong with my failing query.
From https://cloud.google.com/firestore/docs/security/rules-query I understand that a rule is not a filter. According to this document: "If a query could potentially return documents that the client does not have permission to read, the entire request fails.".
Baring that in mind, I have been iterating over my rule, filter and data, and come with the below:
The data: I have NO data in my collection called "MyCollection". As a matter of fact, the collection "MyCollection" has never existed.
The rule:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /MyCollection/{id} {
allow read: if (
(resource.data.readAccess == 0)
)
allow write: if (true)
}
}
}
My failing query (where I have the permission denied error):
Firestore.instance.collection('MyCollection')
.where("readAccess", isLessThanOrEqualTo: 0)
.getDocuments()
.then((_) => print("Success!"));
When I run this query, I get the following error:
W/Firestore(12491): (21.3.0) [Firestore]: Listen for Query(MyCollection where readAccess <= 0) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
My successfull query: (The only difference in this query is that I replaced "isLessThanOrEqualTo" with isEqualTo)
Firestore.instance.collection('MyCollection')
.where("readAccess", isEqualTo: 0)
.getDocuments()
.then((_) => print("Success!"));
Comments:
- I have the same results when I do populate MyCollection with data.
It looks like the query is validated against the rule, not the "potential return documents" as the document https://cloud.google.com/firestore/docs/security/rules-query states. If this is the case I wonder how I will be able to translate the following rule into a filter:
(resource.data.readAccess == 0) || ((request.auth != null) && (resource.data.readAccess <= get(/databases/$(database)/documents/App/$(resource.data.appId)).data.group[request.auth.uid]) )This rule is fairly similar, except that it validates the readAccess level of a document against the group access level in the "App" document for that data's app, for the logged on user. If I can't match the query for a simple rule, I can't imagine what I need to do for this complex rule.
Please advise. Many thanks.