I'm trying to restrict access to a collection based on a users "role" on the document as well as whether they're signed in.
Just checking if they are signed in works:
rules_version = '2';
function isSignedIn() {
return request.auth != null;
}
service cloud.firestore {
match /databases/{database}/documents {
match /workspaces/{workspace} {
allow read: if isSignedIn();
}
}
}
But I want to make it a bit more granular, I'm following this Google guide. When I configure it exactly the same my frontend client errors with FirebaseError: Missing or insufficient permissions. However, testing the rule in the Firebase portal works(?).
rules_version = '2';
function isSignedIn() {
return request.auth != null;
}
function getRole(rsc) {
return rsc.data.access[request.auth.uid];
}
function isOneOfRoles(rsc, array) {
return isSignedIn() && (getRole(rsc) in array);
}
service cloud.firestore {
match /databases/{database}/documents {
match /workspaces/{workspace} {
allow read: if isOneOfRoles(resource, ["owner", "viewer"]);
}
}
}
As mentioned, testing the rule via Firebase works, however when querying from my frontend app it fails.
// VueJS
let workspace = []
async fetchWorkspaces() {
const db = firebase.firestore();
await db.collection('workspaces').get().then(response => {
response.forEach(snapshot => {
this.workspaces.push(snapshot.data());
})
})
}
Database document
I've also tried storing the RBAC for each user as a document in a subcollection and using the following rule
allow read: if isSignedIn() && exists(/databases/$(database)/documents/workspaces/$(workspace)/users/$(request.auth.uid));
Still doesn't work. I can only seem to grant broad access (is signed in)
