DevilWarrior
DevilWarrior

Reputation: 459

Firestore security rules issues with phone number

I'm trying to set some security rules in firebase without luck. Basically I need to check weather the user has been blocked or not based on it's phone number. Here's what I have so far:

service cloud.firestore {

  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if exists(/databases/$(database)/documents/access/+17777777777);
    }

    match /globals/{document=**} {
      allow read: if true;
    }

    match /requests/{document=**} {
      allow write: if true;
    }
  }
}

If I hard-code the number in the rule itself it does what is supposed to. If I use $(reqest.auth.token.phone_number) it does not work.

allow read, write: if !exists(/databases/$(database)/documents/access/$(reqest.auth.token.phone_number));

I've also tried with get as per this question:

allow read, write: if get(/databases/$(database)/documents/access/$(reqest.auth.token.phone_number)).blocked == true ||
      get(/databases/$(database)/documents/access/$(reqest.auth.token.phone_number)).data.blocked == true;

My data structure looks like this

access | +17777777777 | blocked = true

I also tried flipping the structure:

access | blocked | +17777777777 = true

And here is the Authentication payload from the Simulator

{
  "uid": "19687a6s87d68as7d968as7d9a8sd",
  "token": {
    "sub": "19687a6s87d68as7d968as7d9a8sd",
    "aud": "my-app",
    "email": "",
    "email_verified": false,
    "phone_number": "+17777777777",
    "name": "",
    "firebase": {
      "sign_in_provider": "google.com"
    }
  }
}

Upvotes: 4

Views: 1377

Answers (3)

AntPachon
AntPachon

Reputation: 1192

In case it helps, when your authentication is phone authentication, your $uid will be the phone number in international format.

{
  "rules": {
    "users": {
      "$uid" : {
      ".read": "auth != null",
      ".write": "auth != null &&  $uid === auth.token.phone_number"
       }
      }
   }
}

Upvotes: 0

Carlo Beltrame
Carlo Beltrame

Reputation: 443

I found a solution to this problem! As per the documentation, Paths can also be constructed using the path() function. So you can build your path manually using string concatenation:

allow read, write: if exists(path("/databases/" + database + "/documents/access/" + request.auth.token.phone_number));

Upvotes: 4

marson
marson

Reputation: 953

The problem is not in the $(reqest.auth.token.phone_number) method. As stated in this answer, Firestore unfortunately does not support reference field values in document paths at the moment, which is the reason, why do only the hard-coded values work.

Edit

It is strange, but Firestore's example still contradicts my answer above.

Upvotes: 3

Related Questions