So I have these firestore rules here:
match /Customers/{customerId} {
allow read, update, create, delete: if request.auth != null && get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.businessId in resource.data.businessIds || request.auth != null && request.auth.uid == resource.data.uid || request.auth != null && get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.businessId == resource.data.businessId || request.auth != null && get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.customerId == resource.data.customerId;
match /ServiceLocations/{ServiceLocationId} {
allow read, update, create, delete: request.auth != null && get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.businessId == resource.data.businessId;
}
}
And for some reason when I am calling read on /ServiceLocations/{ServiceLocationId} inside the /Customers/{customerId} hierarchy I am getting invalid permissions. But I am confused because the path and values are correct. I am able to read the customerId document fine so there is no issue there, but specifically I cant read the serviceLocationId documents which is a document inside the ServiceLocations subcollection inside the customerId document.
get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.businessId
is a valid path which returns a businessId.
resource.data.businessId
and businessId is a valid field inside the serviceLocationId document and both values do infact equal eachother. Yet it is still returning false.
Attached are two images showing the "Users" document of the user I am sending the request from which includes the businessId field, and the serviceLocationId document I am trying to read from, which also includes the businessId field. And as you can see both values do infact match and the paths are correct.
https://i.stack.imgur.com/vJNPN.png
https://i.stack.imgur.com/W8sgM.png
Here is an example of one of the requests being called invalid:
db.collection("Customers")
.doc(selectedCustomerData.customerId)
.collection("ServiceLocations")
.onSnapshot((snapshot) => {
Am I just doing something wrong? It makes no sense to me. Any help would be appreciated.
CodePudding user response:
I suspect this is a case where the security rules cannot filter your data for you.
Specifically, I think the rules may not be able to enforce this requirement on their own:
get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.businessId ==
resource.data.businessId;
Try passing a filter in the query where you also pass the user's business ID (.where('businessId', '==', 'The business ID of the user')
), or pass the business ID as a custom claim rather then looking it up in a document.