Search code examples
firebasefluttergoogle-cloud-firestorefirebase-authenticationfirebase-security

Firestore security rule doesn't detect phone number from token when on real device


I have an issue where the firestore security rules is unable to filter out users based on their phone number. The rule is set up perfectly and it works well with the simulator but not when I test it out on a real device.

I have a collection of admins where the document ids are the phone numbers. My security rule checks if the phone number of the user is present in the collection and if it does then it returns true. I have set it up according to the answer here as follows-

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isAdmin() {
        return exists(path("/databases/" + database + "/documents/admins/" + request.auth.token.phone_number));
    }
    
    match /tasks/{task=**} {
      allow read: if request.auth.uid != null;
      allow create: if isAdmin();
      allow delete: if isAdmin();
      allow update: if request.auth.uid != null;
    }
  }
}

The create and delete rules in the above snippet are getting approved when I try on a simulator but fails when I test it out on a real device. I have to also mention that if I change the filter from phone number to uid and change the document ids in the collection to the uids, it works out fine with the real device in this manner-

return exists(path("/databases/" + database + "/documents/admins/" + request.auth.uid));

It feels like it is unable to read the token value from auth. I am using the flutter package for firebase auth and firestore to send requests


Solution

  • Solved:

    The problem is that firestore rules is unable to resolve the "+" symbol from the country code. So this is unable to verify if the document with an id of "+919876543210" exists, for example (for Indian country code of +91). All I had to do was to get rid of the "+" symbol while making the documents in the admin collection like so:

    firestore document structure

    and also manually replace the symbol while checking it in the rules like this:

        function isAdmin() {
            return exists(path("/databases/" + database + "/documents/admins/" + request.auth.token.phone_number.replace('\\+', '')));
        }