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.
A DocumentReference refers to a document location in a Firestore database and can be used to write, read, or listen to the location. The document at the referenced location may or may not exist. A DocumentReference can also be used to create a CollectionReference to a subcollection.
rules // is a file used to define the security rules for your Firestore database. firestore. indexes. json // is a file used to define indexes for you Firestore queries.
To access your rules from the Firebase console, select your project, then in the left-hand navigation panel, click Realtime Database. Click Rules once you're in the correct database or storage bucket. To access your rules from the Firebase CLI, go to the rules file noted in your firebase. json file.
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 to get
it as well. Try this:
get(get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role).data.isSuperuser == true;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With