1

I am struggling with Firestore rules to allow access to some resources in a subcollection.

I have some requests documents, that may present a sub-collection named status. My current rules are something like that:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    
    // I use it to check if user is signed in
    function userSignedIn() {
      return request.auth != null;
    }
    
    match /requests/{requestId} {
        
      // I use it to check if user is the owner of the request
      function userCanAccess () {
        return userSignedIn() && request.auth.uid == get(/databases/$(database)/documents/requests/$(requestId)).data.userId;
      }
      
      
      // allow read to logged user who own request
      allow read, update: if userCanAccess();
      
      // anyone can create a new request
      allow create: if true;
      
      // no one can delete the request
      allow delete: if false;
      
      
      
      match /status/{statusId} {
        // allow read and update of status to logged user who own request
        allow read, update: if userCanAccess();
        
        // anyone can create the status
        allow create: if true;
        
        // no one can delete the status
        allow delete: if false;
      }
    }
  }
}

My very first way to check if user had access was by request.auth.uid == resource.data.userId, however it only works for requests documents, not for status documents since they do not have the userId field.

I'm using flutter to make the request with the code:

FirebaseFirestore.instance
            .collection('requests')
            .where('userId', isEqualTo: user.uid)
            .orderBy('requestedOn', descending: true)
            .snapshots()
            .listen((snapshot) {
              // Here I read requests and their status
            });

However I'm getting Error: [cloud_firestore/permission-denied] Missing or insufficient permissions.. How can I solve (or debug) it? Using rules playground in firestore, with the exact same uid, I am able to complete the reading.

ALai
  • 739
  • 9
  • 18

1 Answers1

0

I'm wondering if the get() call may be causing problems. Try this:

function userCanAccess () {
  return userSignedIn() && request.auth.uid == requestId.data.userId;
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • This may not be used as-is: `Invalid type. There is no type for variable 'requestId' that satisfies all clauses.` – ALai Apr 18 '22 at 08:47
  • 1
    Have you tried to debug it with the [Firestore Emulator](https://firebase.google.com/docs/firestore/security/test-rules-emulator)? Also, as described [here](https://stackoverflow.com/questions/70321779/flutter-web-app-cannot-access-the-firebase-cloud-firestore), you can verify if AppCheck is enabled. Meanwhile, you could try any of the following [workarounds](https://stackoverflow.com/questions/46590155/firestore-permission-denied-missing-or-insufficient-permissions). – Osvaldo Apr 18 '22 at 22:37