'Cloud Firestore rules issues outside of console
I've got this set of Firestore rules :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/{path=**} {
match /mycollections/{item} {
function isSignedIn() {
return request.auth != null
&& request.auth.token.firebase.sign_in_provider != 'anonymous';
}
function isInRoles(rsc, roles) {
// return request.auth.uid in request.resource.data.users;
return rsc != null
&& rsc.data.roles[request.auth.uid] == "owner";
//&& rsc.data.roles[request.auth.uid] in roles;
}
function isOneOfRoles(rsc, array) {
return isSignedIn() && isInRoles(rsc, array);
}
function isValidNewItem() {
return request.resource.data.roles[request.auth.uid] == 'owner'
&& request.auth.uid in request.resource.data.users;
}
function isNewSharedUser() {
return request.resource.data.roles[getAuthLogin()] == 'writer'
&& request.auth.uid in request.resource.data.users
&& resource.data.shareLink == request.resource.data.shareLink;
}
function onlyContentChanged() {
// Ensure that title and roles are unchanged and that no new
// fields are added to the document.
return request.resource.data.title == resource.data.title
&& request.resource.data.roles == resource.data.roles
&& request.resource.data.keys() == resource.data.keys();
}
// Split writing into creation, deletion, and updating. Only an
// owner can create or delete a story but a writer can update
// story content.
allow create: if isValidNewItem();
allow delete: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)), ['owner']);
allow update: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)), ['owner'])
|| (isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)), ['writer']) && onlyContentChanged())
|| isNewSharedUser();
allow read: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)), ['owner', 'writer', 'reader']);
// example for permissions
match /items/{subItem} {
allow delete: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer']);
allow update: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer']);
allow read: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer', 'reader']);
allow create: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer']);
}
// example for permissions
match /comments/{comment} {
allow read: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer', 'commenter', 'reader']);
allow create: if isOneOfRoles(get(/databases/$(database)/documents/mycollections/$(item)),
['owner', 'writer', 'commenter'])
&& request.resource.data.user == request.auth.uid;
}
}
}
}
With an authenticated user I can insert new list like this,
db.collection('mycollections').add({
name: 'item ' + Date.now(),
roles: roles,
users: [user.uid],
});
With looks like this in Firestore documents explorer
// doc id "CuwoleyStA5O3rY6Q5de"
{
"roles": {"05CJ88QtXng1NzWQWJkMRB1bkRP2": "owner"}
"name": "Ma nouvelle liste 1646895620631"
"users": ["05CJ88QtXng1NzWQWJkMRB1bkRP2"]
}
After that, I can access it trough the Firestore console using the "rules tester"
But in my app, logged in with an authenticated user, I can't access it the collections of this user in /mycollections/*, I always end up with a an error of "Missing or insufficient permissions".
// query
db.collection("mycollections").where('users', 'array-contains', user.uid)
.onSnapshot((querySnapshot) => { });
=> Error in snapshot listener: FirebaseError: Missing or insufficient permissions.
Where's the rules error? the read access does check that there is a roles for this user which is right, and there is no details to debug the permissions issue.
Solution 1:[1]
Below is the syntax you can use to allow the authenticated user to read and write their own data as per explained in documentation
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Monali Ghotekar |

