Firestore rules to restrict users to their section of the DB - firebase

I am wondering how to restrict firebase to only the specific section of the DB that they own.
Here's basically of what I want:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
}
match /users/{userid} {
allow write: if request.auth.uid == userid;
}
}
}
Can someone explain to me why the above doesn't work?
And how to fix it in order to restrict users to ONLY their data?
Thanks in advance.
Nikita

It doesn't work because of this rule:
match /{document=**} {
allow read: if true;
}
It allows read access to all documents in the database to everyone, unconditionally, and it's overriding the other rule that you've written. Remove this rule if you don't want everyone to be able to read every document in your database.
There is one important thing you need to remember about security rules: if any rule allows access to a document, another rule cannot undo that.

Related

Firestore Security Rule for users with their own collection

What would be the best Firestore rules when users should only be able to read and write their own collections, i.e. the collection name is the same as the userId? Currently I have the following which works, but is it secure enough?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{userId}/{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
I also tried the following which didn't work.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{userId}/{document=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
The first rule is indeed not sufficient, since there is no check on the collection name: any authenticated user can read all the collections named with any users' uid.
The second one should work for your requirements ("Users should only be able to read and write their own collections, i.e. the collection name is the same as the userId"). You are probably having an error somewhere else, e.g. with the code for writing or reading or for authenticating the user. You should share this code in order we double check it

Different security rules for different Firestore collections

I'm currently using Firestore for the first time and trying to understand the security rules a bit. I now my question is really simple and that I could figure out an answer by doing a bit more research but I wanted to be sure that I am doing the right thing, so I thought it would be better to just ask here.
If I had two collections in Firestore one called "A" and the other "B" what would my security rules have to be if I wanted just authenticated users to read, write, update, delete... in A and everyone to read in B but just authenticated users to write, update, delete... in B.
Edit:
Here are the current rules they apply the rules for B to all collections:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if request.auth.uid != null;
}
}
}
If you look at the documentation on authentication in security rules, you will find these rules:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to access documents in the "cities" collection
// only if they are authenticated.
match /cities/{city} {
allow read, write: if request.auth.uid != null;
}
}
}
Modified for your use-case, that'd be something like:
service cloud.firestore {
match /databases/{database}/documents {
match /A/{id} {
allow read, write: if request.auth.uid != null;
}
match /B/{id} {
allow read;
allow write: if request.auth.uid != null;
}
}
}

how to apply security rules to specific collections

I have a question about the security rules.
I know that we can do this to prevent unauthorized users for modifying any node in Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
What if I want to remove this prevention from certain root collections only?
I mean Lets say I have 2 root collections called Tracking, Incoming
Anyone can write or read to that as really no authentications is required for them. But all other collections need to have read/write done by only Authenticated users.
How can I achieve that?
Just call them out and give access. The most permissive rules will override all others. Here, everyone has full access to documents in the collection called all-access:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
match /all-access/{id} {
allow read, write: if true;
}
}
}
But you may want to consider if this is really a good idea. Anyone could jam billions of documents into the collection with these rules. Think carefully about what you want everyone to be able to do here.

How can Firestore check a collection to allow write (rules)

I use a collection called "admin" in Firestore to define which users can write new documents (image below).
At moment, it is controled just by software. I would like to add rules to Firestore. I tried the rule below but it didn't work. What would be the correct rules in that case ?
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth != null;
allow write: if get(/admin/{anyDocument}).data.userId == request.auth.uid;
}
}
}
I'd recommend instead having a users collection with an admin field that can be set to true/false. Then you can do something like:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth != null;
allow write: if get(/users/${request.auth.uid}).data.admin == true;
}
}
}
As far i know this is not possible with your current database structure. Because the push key is not accessible in firestore rules unless it is with in the admin node.
One way is to save the admin with their uid as key like admin/userID/data...
now you can access it
allow write: if get(/databases/$(database)/documents/admin/$(request.auth.uid)).data.userId == request.auth.uid;;

How to restrict new user accounts based on Firestore security rules

Using Firestore, I'm trying to figure out how to restrict new user accounts to those matching a whitelist of emails. The problem is, I don't even know if it's even possible to use security rules to prevent the creation of new user accounts. I've attempted a lot of combinations. This was my best attempt:
service cloud.firestore {
match /users/{userId} {
allow read: if true;
allow create, update: if
request.resource.data.email == "bbbbb#asdfljflsaj.com";
}
}
I've also tried:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if true;
allow create, update: if
request.resource.data.email == "bbbbb#asdfljflsaj.com";
}
}
}
And:
service cloud.firestore {
match /users/{userId} {
allow read: if true;
allow create, update: if
request.auth.email == "bbbbb#asdfljflsaj.com";
}
}
I'm calling 'createUserWithEmailAndPassword' to create the user and keep hoping one of the variations I try is successful, but to no avail at this point in time. I'm starting to wonder if it's even possible. Any help would be greatly appreciated!

Resources