I am seemingly unable to access the resource.id value when trying queries using these rules. when I manually enter the schools id (the commented out line) the data returns fine. I only have 1 school and the doc ID definitely matches the string. but when I ask to match to the resource.id value, my rules return an 'insufficient permissions' error.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
//functions
function signedIn() {
return request.auth.uid != null;
}
function returnUID(){
return request.auth.uid;
}
function getUserData() {
return get(/databases/$(database)/documents/All%20Users/$(request.auth.uid)).data;
}
match /All%20Users/{userID} {
allow read,write: if
signedIn() && returnUID() == userID;
}
match /All%20Schools/{schoolID}{
allow read, write: if
// signedIn() && getUserData().school == "f7asMxUvTs3uFhE08AJr"
signedIn() && getUserData().school == resource.id
}
}
}
my structure is like this
All Schools / school (document) / Classrooms (subcollection) All Users / User (document) (each user doc has a classroomID associated to it)
as a point of reference this is a query that is successful
var docRef = db.collection("All Users").doc(uid).get()
and the one that is failing
db.collection("All Schools/" + properties.schoolid + "/Classrooms").onSnapshot()
[update] the working set of rules!
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
//functions
function signedIn() {
return request.auth.uid != null;
}
function returnUID(){
return request.auth.uid;
}
function getUserData() {
return get(/databases/$(database)/documents/All%20Users/$(request.auth.uid)).data;
}
match /All%20Users/{userID} {
allow read,write: if
signedIn() && returnUID() == userID;
}
match /All%20Schools/{schoolID}{
allow read, write: if schoolID == 'f7asMxUvTs3uFhE08AJr'
}
match /All%20Schools/{schoolID}/Classrooms/{classId} {
allow read, write: if getUserData().school == schoolID;
}
match /All%20Schools/{schoolID}/Student%20List/{student} {
allow read, write: if getUserData().school == schoolID;
}
match /All%20Schools/{schoolID}/Staff/{staff} {
allow read, write: if getUserData().school == schoolID;
}
}
}
The following rules will be effective on documents of 'All Schools' collection only and not documents of 'Classrooms' sub-collection:
match /All%20Schools/{schoolID} {
// ...
}
That's why db.collection("All Users").doc(uid).get()
works and fetching 'Classrooms' collection fail since you do not have any rules specified for it. Although you had a recursive wildcard earlier (before editing the question), resource
object contains data of those documents being matched in 'Classrooms' sub-collection and hence getUserData().school == resource.id
failed too.
That being said, try specifying rules for 'Classrooms' sub-collection as well:
match /All%20Schools/{schoolID}/Classrooms/{classId} {
allow read, write: if getUserData().school == schoolID;
}