I am trying to base a security rule on a reference to another object.
I have a collection of users and collection of roles. A user object has a field called "role" that is a reference to a particular document in the roles collection.
users
id
name
role <-- reference to particular role
roles
id
name
isSuperUser
The goal here is to allow a user with a particular role (the role with isSuperUser == true) to edit any other role or it's sub-collections;
Here are my rules that I would have thought would have worked:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId=**} {
allow read, write: if request.auth.uid == userId;
}
match /roles/{roleId=**} {
function isSuperUser() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role.isSuperuser == true;
}
allow read: if request.auth.uid != null;
allow write: if isSuperUser();
}
}
I have confirmed the following works, but it's not really that useful...
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role != null;
If there is a better way to accomplish role base security, I am all ears.
The lack of any debugging tools makes this quite frustrating.
I know it's been a while since the original question but I've had a similar issue and I hope this could help you or others.
Your condition is:
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role.isSuperuser == true;
But
role
is a reference, which (apparently) means you need toget
it as well. Try this:get(get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role).data.isSuperuser == true;
Have you tried to move the wildcard to a nested path?