Eray Erdin
Eray Erdin

Reputation: 3179

Firestore rule does not permit list operation

I have Firestore rules as such:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isAuthenticated() {
      return request.auth.uid != null;
    }
    function ownsData(id) {
      return request.auth.uid == id;
    }
    match /feedpoints/{fid} {
      allow read: if request.auth != null;
    }
    match /feedpoints/{fid} {
      allow write: if false;
    }
    match /profiles {
      allow list: if false;
      match /{pid} {
        allow read: if isAuthenticated() && request.auth.uid == pid;
      }
      match /subscriptions {
        allow list: if isAuthenticated();
        match /{sid} {
          allow read, write, list: if isAuthenticated() && ownsData(sid);
        }
      }
      match /bookmarks {
        allow list: if isAuthenticated();
        match /{bid} {
          allow read, write, list: if isAuthenticated() && ownsData(bid);
        }
      }
    }
  }
}

What I'd like to do is to be able to list all the documents under /profiles/{pid}/subscriptions, but, in my Flutter app, I always get an error saying:

[cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.

Another thing that might be related:

Listen for Query(target=Query(profiles/qguefZV3SjOpf1CGdIJrmufoUBPK/subscriptions order by name);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=No matching allow statements, cause=null}

I'm using Firebase Emulator for testing out.

Why do I get permission denied error despite explicitly station allow list: if isAuthenticated() under match /subscriptison?

Upvotes: 1

Views: 125

Answers (1)

Mark Munene
Mark Munene

Reputation: 830

As per the documentation,

When nesting match statements, the path of the inner match statement is always relative to the path of the outer match statement.

Therefore, the subscriptions match statement should be inside match /{pid} since it's a subcollection inside the profiles collection.

 match /{pid} {
    allow read: if isAuthenticated() && request.auth.uid == pid;
    match /subscriptions {
    allow list: if isAuthenticated();
    match /{sid} {
      allow read, write, list: if isAuthenticated() && ownsData(sid);
    }
    }
  }

Upvotes: 2

Related Questions