Firestore Security Rule: How to validate Incoming Read Requests with Subcollection Field Values

I have a Firestore collection named 'users' that stores user information. Within this collection, there is a subcollection named 'shops,' containing documents listing the shops each user is permitted to access. The 'shops' subcollection includes a field named 'shopId,' which serves as a unique identifier for each shop.

Each incoming read request contains a 'shopId.' I am looking to create a Firestore security rule that validates each incoming request. Specifically, the rule should verify whether the 'shopId' in the incoming request matches the 'shopId' in the 'shops' subcollection of the user document associated with the request, then grant read permission to document from any collection with shopId matching the client request.

Here is my code, but is not working.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow read access to user documents if conditions are met
    match /users/{userId} {
      allow read: if request.auth != null &&
        // Check if the user document exists and if the 'shopId' in the request matches the 'shopId' in the user document
        exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId)) &&
        request.data.shopId == resource.data.shopId;
      
      // Allow reading all documents under any collection for the specified shopId
      match /{collectionId}/{document=**} {
        // Check if the user document exists and if the 'shopId' in the request matches the 'shopId' in the user document
        allow read: if request.auth != null &&
          exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId)) &&
          request.data.shopId == resource.data.shopId;
      }
    }
  }
}

1 reply