Reputation: 33
I have some trouble with setting up my rules for a firestore project. I try to learn the database setup but can't find any solution for this. So there's no problems when i try to get a document from my collection "lists". But when i try to get all of the documents in the collection "lists" xcode tells me "Missing or insufficient permissions". My goal is to have users that are able to create documents in collection "lists" but they can only read the documents in "lists" where they appear in the document array "members".
Right now I can add documents in collection("lists") without any problem but I can't read them. I can only read them one by one from xcode with a specific target.
Any tips or ideas?
service cloud.firestore {
match /databases/{database}/documents {
match /{documentId} {
allow read: if request.auth.uid != null;
}
match /lists/{docId} {
allow write: if request.auth.uid != null;
allow read: if request.auth.uid in resource.data.members
}
}
}
Xcode.
//working
let docRef = db.collection("lists").document("j0hHA5TLPETf6JRMbC1s")
docRef.getDocument { ...
//not working due to permission failed
db.collection("lists").getDocuments() { ...
Upvotes: 2
Views: 68
Reputation: 317427
Your rule doesn't work because it assuming that the rule will filter out all the documents that don't match the rule. This is not how security rules work. Security rules are not filters. From the linked documentation:
When writing queries to retrieve documents, keep in mind that security rules are not filters—queries are all or nothing. To save you time and resources, Cloud Firestore evaluates a query against its potential result set instead of the actual field values for all of your documents. If a query could potentially return documents that the client does not have permission to read, the entire request fails.
The client must only request documents that would satisfy the rules. Right now, the query is asking for ALL documents in the lists collection, regardless of whether or not the client has access to them. This is going to fail the security rule, because it's attempting to read documents that it doesn't have access to.
What you need to do instead is make your query only request documents that are readable by the user. This means that you should probably be using an array-contains filter on the client to match only documents that the rule would allow it to read.
Upvotes: 3
Reputation: 265
Actually, you are on the right path, I think if you change your code like this, it will work.
Instead of this:
match /{documentId} {
allow read: if request.auth.uid != null;
}
Use this:
match /lists {
allow read: if request.auth.uid != null;
}
So when you try to access lists
without documentId
, it will check the auth.uid
.
But when you try to access a document ex. lists/1
, it will check whether that user exists in the array.
Upvotes: 0