how to apply security rules to specific collections - firebase

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.

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

Firestore rules to restrict users to their section of the DB

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.

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;
}
}
}

Firestore security rules allow user access to their data

I want to write a rule like this:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/{document=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
That is, I want to allow all read and write operations to all of a user's data if that user is the authenticated user.
Unfortunately that does not work. I get an error specifying that I don't have permission to access the data.
This code solved the problem:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
match /{document=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
}
I think it's because you need to grant access to /users/{userId}, as well as /users/{userId}/{anyDoc=**}.
From the official documentation:
Another common pattern is to make sure users can only read and write
their own data:
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.uid == userId;
allow create: if request.auth.uid != null;
}
}
}
If your app uses Firebase Authentication, the request.auth variable
contains the authentication information for the client requesting
data.
Please note that this only works if you have made a 'users' table in your database and populated it with users that are known to your application (possibly copied from FireBase's users section Authentication/users in the webconsole).
AfaIcs you cannot refer to the Firestore authenticated users table this way. I found this lack of information very confusing since all examples and Firestore documentation make you believe that you can access the users created through the webconsole this way, invariably resulting in an 'access denied' messages when trying to read from a users table...

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