If my firestore looks like this:
/domain path (eg. xyz.com)/users and other data/ecc
which rule can I set to allow user to access only the domain path they are in? Something like:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} { <-- what here
allow read, write: if request.auth <-- what here ;
}
}
}
edit: actual firestore screenshot
It seems you have user's domain as collection name so you can use a wildcard as shown below:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{colName}/{docId} {
allow read, write: if colName == request.auth.token.email.split("#")[1];
}
}
}
This rule will check if the collection name is equal to requesting user's domain in their email.
However, this above rule will be applied for all the collections in your database so I'll recommend creating a single collection "users" and storing the domain name as a field as shown below if possible:
users -> { userId }
(col) (doc)
// document in users collection
{
email: "user#domain.tld",
domain: "domain.tld",
...otherFields
}
You can then easily access the domain name in the security rules from document data.
Related
I have an Events collection and a Users collection. My Event page increments a counter (in Users collection) when an event is uploaded. I want to limit the number of events per user to 10.
This what I have so far and it doesn't seem to work as expected:
rules_version = '2';
service cloud.firestore {
match /databases/collection/Events{
allow read;
allow write: if 50 >
get(/databases/collection/Users/$(request.auth.uid)).data.numberOfEvents;
}
}
//Tried this:
rules_version = '2';
service cloud.firestore {
// Do not change this
match /databases/{database}/documents {
// Path to your document
match /Users/{doc=**} {
allow read;
allow write;
}
match /Events/{doc=**} {
allow read;
allow write: if get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.numberOfEvents < 50;
}
}
}
Actually the last one seems to work, let me test some more, thanks for all help!
It seems to work! Thanks!
You are not specifying the document path correct. Assuming events and users are both root level collections. Try the following rules:
rules_version = '2';
service cloud.firestore {
// Do not change this
match /databases/{database}/documents {
// Path to your document - collection names are case sensitive
match /events/{eventId} {
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.numberOfEvents < 10;
}
}
}
You should however not allow users to write to numberOfEvents directly from client as they can reduce the number and try to add more events. Firestore triggers for Cloud functions might be useful here to increment/decrement the value securely from backend.
I am collecting my admin users uid's as documents in "admins" collection. I want to allow users to read if they have their uid's in that collection as a document.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /admins/{document=**} {
allow write; // Everyone should be able to write
allow read: if request.auth.uid == ; // Only read if /admins/{youruid}
}
}
}
You can use exists() to check if a document exists. Try refactoring your rules as shown below:
match /admins/{document=**} {
allow read: if exists(/databases/$(database)/documents/admins/$(request.auth.uid));
// Only read if /admins/{youruid}
}
You can read more about exists() in the documentation.
Firebase keep telling me
We've detected the following issue(s) with your security rules:
any user can read your entire database
I have changed the rules but that rules doesn’t work in my app because all user can read from db and only authenticate user can write to db.
Firebase says that write and read should be performed until we login. But in my case every user can read and only login user can write.
Any ideas how to solve this ? or I'm I doing it wrong ?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
allow write: if request.auth != null;
}
}
}
Can you set your read to false explicitly?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if false;
allow write: if request.auth != null;
}
}
}
That should do it. Let me know if it persists.
The root cause is that even though you are allowing only authenticated users to read or write but they have access to the whole database as mentioned in the Google Cloud Firestore Documentation. That also means any authenticated user can write anything in your database.
If you database has a separate document for each user, I would suggest using the following rules which allows users to write/read their own data only.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid === userId;
}
}
}
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
I'm using Firebase Firestore to collect user information in my current Android app. But I didn't quite get the Firestore rules. I write the rule like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
But I want to user access the database even there's no current user because when the user sign up I'm checking the database if there's a current phone number in the database if not user can sign up this phone number. Thank you
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
Not recommended: Read and write access to all users.
Have a look at Fix insecure rules documentation from firebase for more details.