I wonder if there is any simpler way to achieve this rule. Just started to experiment with firestore.
match /emails/{emailId} {
allow write: if request.resource.data.attachments.size() == 0
|| request.resource.data.attachments.size() == 1 && request.resource.data.attachments[0].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[0].filetype == 'image/png' || request.resource.data.attachments[0].filetype == 'image/jpg' || request.resource.data.attachments[0].filetype == 'application/vnd.ms-excel')
|| request.resource.data.attachments.size() == 2 && request.resource.data.attachments[0].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[0].filetype == 'image/png' || request.resource.data.attachments[0].filetype == 'image/jpg' || request.resource.data.attachments[0].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[1].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[1].filetype == 'image/png' || request.resource.data.attachments[1].filetype == 'image/jpg' || request.resource.data.attachments[1].filetype == 'application/vnd.ms-excel')
|| request.resource.data.attachments.size() == 3 && request.resource.data.attachments[0].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[0].filetype == 'image/png' || request.resource.data.attachments[0].filetype == 'image/jpg' || request.resource.data.attachments[0].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[1].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[1].filetype == 'image/png' || request.resource.data.attachments[1].filetype == 'image/jpg' || request.resource.data.attachments[1].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[2].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[2].filetype == 'image/png' || request.resource.data.attachments[2].filetype == 'image/jpg' || request.resource.data.attachments[2].filetype == 'application/vnd.ms-excel')
|| request.resource.data.attachments.size() == 4 && request.resource.data.attachments[0].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[0].filetype == 'image/png' || request.resource.data.attachments[0].filetype == 'image/jpg' || request.resource.data.attachments[0].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[1].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[1].filetype == 'image/png' || request.resource.data.attachments[1].filetype == 'image/jpg' || request.resource.data.attachments[1].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[2].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[2].filetype == 'image/png' || request.resource.data.attachments[2].filetype == 'image/jpg' || request.resource.data.attachments[2].filetype == 'application/vnd.ms-excel') && request.resource.data.attachments[3].fileSize < 3 * 1024 * 1024 && (request.resource.data.attachments[3].filetype == 'image/png' || request.resource.data.attachments[3].filetype == 'image/jpg' || request.resource.data.attachments[3].filetype == 'application/vnd.ms-excel');
}
Cloud Firestore and Cloud Storage rules use a language based on the Common Expression Language (CEL), that builds on CEL with match and allow statements that support conditionally granted access.
Cloud Firestore Security Rules allow you to control access to documents and collections in your database. The flexible rules syntax allows you to create rules that match anything, from all writes to the entire database to operations on a specific document.
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.
We don't allow loop constructs in Rules because we rely upon several optimization techniques that are much harder with more complex structures. We also don't charge compute time for Rules execution, which means we don't want them getting too complex and potentially abusive.
With the repetition in your rules, I'd highly encourage using the function() feature to simplify. For example this is < 1/3 the size:
match /emails/{emailId} {
function attachments (){
return request.resource.data.attachments();
}
function attach_cnt () {
return attachments().size();
}
function valid_size(attach) {
return attachments()[attach].fileSize < 3 * 1024 * 1024;
}
function valid_type(attach) {
return (attachments()[attach].filetype == 'image/png'
|| attachments()[attach].filetype == 'image/jpg'
|| attachments()[attach].filetype == 'application/vnd.ms-excel');
}
allow write: (attach_cnt() < 1 || (valid_size(0) && valid_type(0)))
&& (attach_cnt() < 2 || (valid_size(1) && valid_type(1)))
&& (attach_cnt() < 3 || (valid_size(2) && valid_type(2)))
&& (attach_cnt() < 4 || (valid_size(3) && valid_type(3)))
}
Here's how I simplified it (worth double-checking as I might have mistyped).
attachments
for the request data being accessed since it's used a bunched - this made it a lot easy skim the rules.attach_cnt
for the number of attachments since that was checked a lot.valid_size
for that test, using a parameter attach
that I could pass it.valid_type
which worked the same way, but did the check to make sure it was a valid type.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