I am using Firebases Firestore. Is it possible to simplify this rules and how?
I want people that are not authorized to only read the public docs and not have acces to private collection..
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
// PUBLIC--------------------------------
match /Contacts/{doc} {
allow read;
allow write: if request.auth != null;
}
match /ReferenceCategories/{doc} {
allow read;
allow write: if request.auth != null;
}
match /ReferencePlaces/{doc} {
allow read;
allow write: if request.auth != null;
}
match /References/{doc} {
allow read;
allow write: if request.auth != null;
}
match /SiteData/{doc} {
allow read;
allow write: if request.auth != null;
}
// PRIVATE-------------------------------
match /ClothingTypes/{doc} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
match /Employees/{doc} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
match /Users/{doc} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
}
}
}
Related
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{document} {
allow create: if request.auth != null;
allow read,update: if request.auth != null && request.auth.uid == resource.data.uid;
allow delete: if false;
}
match /Home/{document} {
allow create: if request.auth != null;
allow read,update: if request.auth != null && request.auth.uid == resource.data.uid;
allow delete: if false;
}
match /Contacts/{document} {
allow create: if request.auth != null;
allow read: if request.auth != null;
allow write: if false;
allow delete: if request.auth.uid == resource.data.uid;
}
match /Medicals/{document} {
allow create: if request.auth != null;
allow read,update: if request.auth != null && request.auth.uid == resource.data.uid;
allow delete: if false;
}
match /{document=**} {
allow read;
allow write: if (request.auth.uid != null);
}
}
}
I wrote this but its not working:
isAdmin(): not working
isLogin(): working well
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write : if false;
}
function isLogin() {
return request.auth != null
}
function isAdmin() {
return isLogin() &&
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true
}
// allow for only auth & is admin
match /users/{userId} {
allow read, write : if isAdmin();
}
}
Thanks in advance
You need to pass the database variable as an argument in your function like this:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write : if false;
}
function isLogin() {
return request.auth != null
}
function isAdmin(database) {
return isLogin() &&
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true
}
// allow for only auth & is admin
match /users/{userId} {
allow read, write : if isAdmin(database);
}
}
}
I'm trying to write a rule in firebase security console with get() but I can't get resource data anyhow... I want documents and their subcollections to be readable to user, if user uid is in document field, array or map.
My collection structure:
/boards/(boardId)/...much more
Fields in (boardId) document:
name: "Board name"
ownerId: "MYID12345"
guestsId(array): ["MYID12345"]
guestsMap(map): [MYID12345: true]
Security rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /boards/{boardId=**} {
// rules here
}
}
}
What I have tried so far:
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).data.guestsMap[request.auth.uid] == true;
allow read: if request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).data.guestsMap;
allow read: if request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).data.guestsMap[true];
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).request.data.guestsId[request.auth.uid];
allow read: if request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).data.guestsId;
allow read: if request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).request.data.guestsId;
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).data.ownerId == request.auth.uid;
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).data.ownerId == "MYID12345";
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).resource.data.ownerId == request.auth.uid;
allow read: if get(/databases/$(database)/documents/boards/$(boardId)).request.data.ownerId == request.auth.uid;
None of these worked, always getting:
ERROR FirebaseError: Missing or insufficient permissions.
allow read: if true, makes the application run normally.
I'm sticking to the documentation but it's not working for me...
#update
match /boards/{boardId=**} {
allow read: if resource.data.ownerId == request.auth.uid;
}
Also can't use it like this, because then, every subcollection is looking for ownerId field in it's documents, and ownerId or friend list array are only in board document.
#update
I tried to do like so, but it didn't help:
match /boards/{boardId} {
allow read, write: if request.auth.uid in resource.data.guestsId || request.auth.uid == resource.data.ownerId;
allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid));
function passResource() {
return request.auth.uid in resource.data.guestsId || request.auth.uid == resource.data.ownerId;
}
match /categoryList/{categoryId} {
allow read, write: if passResource();
}
...
}
What am I missing here?
Okay I found a working solution:
match /databases/{database}/documents {
match /boards/{boardId} {
allow read: if request.auth.uid in resource.data.guestsId || request.auth.uid == resource.data.ownerId;
allow write: if request.auth.uid == resource.data.ownerId;
allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid));
function isAllowed() {
return request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).data.guestsId || request.auth.uid == get(/databases/$(database)/documents/boards/$(boardId)).data.ownerId;
}
match /categoryList/{category} {
allow read, write: if isAllowed();
match /taskList/{task} {
allow read, write: if isAllowed();
}
}
...
}
Also funny it didn't want to work like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /boards/{boardId=**} {
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/boards/$(boardId)).data.guestsId || request.auth.uid == get(/databases/$(database)/documents/boards/$(boardId)).data.ownerId;
allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid));
}
}
because:
Error: simulator.rules line [5], column [49]. Property guestsId is undefined on object.
I am getting the error:
FirebaseError: Missing or insufficient permissions when trying to view a document in a subcollection. I'm trying to get at the documents 'character' in subcollection 'settings'.
systemsCol()
.doc(localStorage.getItem("systemId"))
.collection('settings')
.doc('character')
How can i set all items and subdocuments for each 'system' document?
Here are my permissions
service cloud.firestore {
function authed (auth, data){
return auth.uid == data.owner.uid || auth.token.email in data.collaborators;
}
match /databases/{database}/documents {
match /systems {
allow read, write:
if request.auth.uid != null;
match /{systemId} {
allow list, create:
if request.auth.uid != null;
allow get, update, delete:
if authed(request.auth, resource.data);
}
match /{systemId}/{document=**} {
allow read, write:
if authed(request.auth, resource.data);
}
}
}
}
Also tried
service cloud.firestore {
function authed (auth, data){
return auth.uid == data.owner.uid || auth.token.email in data.collaborators;
}
match /databases/{database}/documents {
match /systems {
allow read, write:
if request.auth.uid != null;
match /{systemId} {
allow list, create:
if request.auth.uid != null;
allow get, update, delete:
if authed(request.auth, resource.data);
match /{document=**} {
allow read, write:
if authed(request.auth, get(/systems/{systemId}).data);
}
}
}
}
}
I am using Cloud Firestore and I can't seem to get the "IN" operator to work with the security rules. I have tried using array and map but neither work. Of course when I set it to allow read, write; it works fine. What am I doing wrong?
Rules:
service cloud.firestore {
match /databases/{database}/documents {
match /rooms/{roomId=**} {
allow read, write: if request.auth.uid in resource.data.users;
allow read, write: if request.auth.uid in resource.data.users2;
allow create: if request.auth != null;
}
match /user-rooms/{userId} {
allow read, write: if userId == request.auth.uid;
}
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
allow get, create: if request.auth != null;
}
}
}
Client:
db.collection("rooms")
.document(self.room.getRoomId())
.collection("messages")
.addSnapshotListener { .....
//Room is: d6l946swspNSouANzVdZ
//Username is: eX8gkxJNDREv
data will return it's direct children not it's sub-children(users and users2) so you should use get and exists instead of in
match /rooms/{roomId=**} {
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/rooms/$(roomId)/users/$(request.auth.uid)).data;
allow read, write: if exists(/databases/$(database)/documents/rooms/$(roomId)/users2/$(request.auth.uid));
allow create: if request.auth != null;
}
checkout the doc
You're trying to access a variable named "users" inside resource.data which doesn't exist. The resource variable contains data from the object that is currently being written to the database.
What you're probably trying to do is check if this users exist in the fields users and users2, which can be achieved with the rules:
match /rooms/{roomId=**}{
allow read, write: if (exists(/databases/$(database)/documents/rooms/$(roomId)/users2/$(request.auth.uid)) ||
request.auth.uid in get(/databases/$(database)/documents/rooms/$(roomId)).data.users);
allow create: if request.auth!=null;
}