Search code examples
regexfirebasegoogle-cloud-firestorefirebase-security

Firestore Regex Rules - Security


I'm trying to use regex to match an email for Firestore rules.

return request.resource.data.email.matches('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i');

I pulled the regex directly from the Firebase documentation. https://firebase.google.com/docs/reference/security/database/regex

The problem is it doesn't match my email. I put it into a regex checker and it seems like the \\. is causing the issue. It won't pick up my email, but if I try \.(which will work in the regex validator) - then Firestore rules throw an error.

firestore.rules:47:83 - ERROR Missing 'match' keyword before path.
!  firestore.rules:47:83 - ERROR Unexpected '/.'.
!  firestore.rules:47:85 - ERROR mismatched input '[' expecting {'{', '/', PATH_SEGMENT}
!  firestore.rules:47:95 - ERROR Unexpected '$'.
!  firestore.rules:47:96 - ERROR Missing 'match' keyword before path.
!  firestore.rules:47:99 - ERROR mismatched input ')' expecting {'{', '/', PATH_SEGMENT}
!  firestore.rules:81:5 - ERROR Unexpected 'allow'.
!  firestore.rules:87:3 - ERROR Unexpected '}'.

For reference the email I'm testing against is

email: "[email protected]"

Solution

  • There are a few problems in your rules.

    1. You're mixing literal RegEx syntax (starting/ending with /) with string-based syntax (enclosed in quotes).
    2. The /i at the end indicates you want a case-insensitive match, but I don't think that is supported in Firestore security rules.

    The simplest solution is to make it all into a string, and just add a-z ranges to allow both uppercase and lowercase.

    This works for me:

    match /77724566/{doc} {
      allow write: 
        if request.resource.data.email.matches(
          '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$'
        );
    }
    

    In here 77724566 is my collection name.