I have the following firestore structure, basically 3 collections
publicdata protecteddata1 protecteddata2
I want to have protecteddata1 and protecteddata 2, and really the entire firestore database as authenticated users only. But i want the public to have readonly access to 'publicdata' collection..
The following is my attempt but it doesn't work
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
allow write: if (request.auth.uid != null);
}
match /publicdata {
allow read;
}
}
}
If you receive an alert that your Cloud Firestore database isn't properly secured, you can resolve the vulnerabilities by modifying and testing your Cloud Firestore Security Rules. To view your existing Security Rules, go to the Rules tab in the Firebase console.
Use the Firebase console To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.
The Firebase Admin SDKs access your database using a service account. Service accounts ignore the Cloud Firestore Security Rules, similar to how you can edit documents in the Firebase Console directly yourself.
To be honest, without Firebase Authentication, it's not possible to accept writes to a database without Authentication and also avoid abuse, since anyone could write anything from anywhere on the internet.
You can use the following functions I created to do this
function isUserAuthenticated() {
return request.auth.uid != null;
}
You can then use it like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if isUserAuthenticated();
}
match /publicdata/{itemId} {
allow read : if true;
allow create : if isUserAuthenticated();
allow update: if isUserAuthenticated();
allow delete: if isUserAuthenticated();
}
/* Functions */
function isUserAuthenticated() {
return request.auth.uid != null;
}
}
}
The recursive wildcard here is allowing access to all collections:
match /{document=**} {
allow read;
allow write: if (request.auth.uid != null);
}
Once any rule allows access to a collection, that access cannot be revoked by any other rule.
What you will have to do is call out each individual collection in its own rule. Yes, that's kind of a pain, but it's your only option. It also makes it very clear to the reader of your rules what you intend to allow for each collection.
Also worth noting that this rule doesn't actually do anything at all, because it doesn't match any documents:
match /publicdata {
allow read;
}
If you want to match documents in the publicdata collection, it needs a wildcard that matches document within that collection:
match /publicdata/{id} {
allow read;
}
Remember that rules match documents for access, not collections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With