I have a Firestore collection structured like this:
/database/{database}/documents/group/{group}/...
Each group has a field named "members" that is an array of userIDs:
group: {
members: [
"user01",
"user02",
]
}
I have an iOS (Swift) snapshot listener on this collection:
Firestore.firestore().collection("group").whereField("members", arrayContains: Auth.auth().currentUser.uid)
.addSnapshotListener {...
Which works if I leave the Firestore Rules mostly open with:
match /group/{group}/{document=**} {
allow read: if request.auth.uid != null;
}
However, when I try to secure the collection to only allow the above snapshot (and not a request to other documents in the collection), my permissions are not correct. This is what I have tried:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /group/{group}/{document=**} {
allow read: if request.auth.uid in get(/database/$(database)/documents/group/$(group)).data.members || request.auth.uid in get(/database/$(database)/documents/group/$(group)).members;
}
}
}
I have also tried:
match /group/{group} {
allow read: if request.auth.uid in resource.data.members;
}
Which appears to work, but does not allow me to access child collections of the document. I need the get()
rules method to work.
Similar solutions seem to have worked for others on SO. Is there another way to allow this type of permission on a document and child collections or perhaps I am overlooking something obvious with this solution?
EDIT
After reading through more docs, it appears that this solution works:
match /group/{group} {
allow read: if request.auth.uid in resource.data.members;
match /child_collection/{document=**} {
allow read: if request.auth != null;
}
}
I'll give some time before I list that as the answer in case anyone more experienced has a better solution.