I need to allow access to all documents only to authenticated users and prevent of writing invalid data.
For example I have a field that should contain only long type of data.
The problem is that if I have a rule that allow to write for authenticated user, then it ignores all other rules.
Here is what I have now:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Offers/{Offers} {
allow write: if request.resource.data.val1 is float
&& request.resource.data.val2 is float;
}
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
The problem comes from using =**
in this rule:
match /{document=**} {
allow read, write: if request.auth != null;
}
This is saying that anyone who is authenticated has full read/write access to all documents in this collection, and in all collections under it. And once you've granted somebody this permission, you can't take it away at a lower level.
The solution is to remove the =**
:
match /{document} {
allow read, write: if request.auth != null;
}
Now authenticated users can still read/write all documents in this collection, but not in all collections under it. For the offers, you'll then want to add back that condition:
match /Offers/{Offers} {
allow write: if request.auth != null
&& request.resource.data.val1 is float
&& request.resource.data.val2 is float;
}
So you'll end up repeating some of the conditions, which is normal. You'll often see these conditions then encapsulated in a function, so that it's easier to both reuse them, and to understand the meaning.
For example, with two named functions, the rules could become:
match /{document} {
allow read, write: if isAuthenticated();
}
match /Offers/{Offers} {
allow write: if isAuthenticated() && isValidOffer();
}