0
votes

I am trying to set-up Firestore permission rules. This is my data as well as my rules and my authentication payload.

enter image description here

enter image description here

enter image description here

service cloud.firestore {
  match /databases/{database}/documents {
    match /questions/{questionId} {
      allow create: if isAdmin() && emailVerified();
      allow read: if isAdmin() && emailVerified();
      allow update: if isAdmin() && emailVerified();
      allow delete: if isAdmin() && emailVerified();
    }

    match /users/{userId} {
        allow get: if isOwner(userId) && emailVerified();
    }
  }

  function isAdmin2() {
    return request.auth.uid == 'CoKtrTQEA8P18v0jtcDUt766rVl1';
  }

  function isAdmin() {
    return getUserData().roles.keys().hasAny(['admin']);
  }

  function getUserData() {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
  }

  function emailVerified() {
    return request.auth.token.email_verified;
  }

  function isOwner(userId) {
    return request.auth.uid == userId;
  }

  function isSignedIn() {
    return request.auth != null;
  }

}

{
  "uid": "CoKtrTQEA8P18v0jtcDUt766rVl1",
  "token": {
    "sub": "CoKtrTQEA8P18v0jtcDUt766rVl1",
    "aud": "flying-pigs",
    "email": "[email protected]",
    "email_verified": true,
    "phone_number": "",
    "name": "",
    "firebase": {
      "sign_in_provider": "google.com"
    }
  }
}

When trying to read the questions list, isAdmin() will return false every time while isAdmin2() will work just fine, but it is hardcoded.

What am I missing?

1
What does the emulator have to say about the request? It will indicate which part of the request is failing. Does it work if you try to read the document directly vs. the collection? - Kato
@Kato The simulator says “Simulated read denied”, and highlights the allow read: if isAdmin() && emailVerified(); line. How should I try to read the document directly? Thanks - Tănase Hagi
Please add specifics about your simulator query to the post. Be as specific as possible. The goal is to make the problem reproducible. See how to ask and creating an mcve. - Kato

1 Answers

0
votes

Once I had the same problem, I end up doing something like this:

function isAdmin(request) {
    return ['admin'] in getUserData(request).roles
}

Make sure your functions receive request as parameter, your isAdmin and getUserData are not currently receiving it. how this helps