Is it costly (i.e. roughly how many reads & how much are we charged in $) to have a firestore security like this:
 match /profiles/{document=**} {
   allow create: if request.auth.uid != null
   && (request.resource.data.firstName is string && resource.data.firstName != request.resource.data.firstName)
   && (request.resource.data.lastName is string && resource.data.firstName != request.resource.data.firstName)
  && (request.resource.data.username is string && resource.data.username != request.resource.data.username)
  && (request.resource.data.email is string && resource.data.email != request.resource.data.email)
}
                According to the documentation, you are billed for get() and exists() requests in your security rules:
Using the get() and exists() functions, your security rules can evaluate incoming requests against other documents in the database.
Continued:
Using these functions executes a read operation in your database, which means you will be billed for reading documents even if your rules reject the request. See Cloud Firestore Pricing for more specific billing information.
So, if your rules don't use get() or exists(), then you don't have additional billing associated with the rules. It appears you are not using either of those functions here, so I would anticipate no additional billing.
I just tested out this simple security rule:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isAuthor() {
      return request.auth != null &&
             request.auth.uid == resource.data.author.uuid;
    }
    match /posts/{postId} {
      allow read, write: if isAuthor();
    }
  }
}
With a simulated read operation and an "incorrect" UID, I read a document 100 times and it was denied 100, and it counted towards the billing 100 times as read operations as you can see in this spike.

So Yes, using resource is costly. No matter if it is denied or passed, it'd count towards your billing and you are subject to billing fraud due to Firebase's naturally amazing system.
You'd need to implement a lot of cloud workarounds to mitigate this in production with many users since there's no straight solution or one way to protect against such attacks.
Edit:
Official Firebase Docs says
The resource is the current value within the service represented as a map of key-value pairs. Referencing
resourcewithin a condition will result in at most one read of the value from the service. This lookup will count against any service-related quota for the resource. For get requests, the resource will only count toward quota on deny.
That means that if your condition does not reference resource, it will not get counted; it is also more accurate to say that if your condition does not access the resource field, it will not be counted. Bear in mind that even if you accessed resource and your rule succeeded, you'd get only 1 read operation at most as mentioned, not two. It only counts on deny as we've already tested.
(1) This will deny and not count towards your reads:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false && resource.data
    }
  }
}
(2) This will deny but count towards your reads because you accessed resource.
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if resource.data.readable; // always false
    }
  }
}
(1) Resulted in 0 usage with 100 denied requests.
(2) Resulted in 100 usage with 100 denied requests.
Here's a tip to know if you're going to get billed a read operation or not.
If you see a resource on the right, that means this rule has accessed resource, which means it billed you a read operation.
Such as:
And (.readable is false in the document):

If you don't see resource on the right, that means this rule has not accessed resource, and thus hasn't billed you a read operation.
Such as (resource.data is always true):

References:
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