flutterfirebasegoogle-cloud-firestorefirebase-authenticationfirebase-security

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


I am trying to setup my security rules for my cloud firestore and just can't figure out the problem.

This is my code

  Future<List<Document>> getDocumentsForGroup(String groupId) async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) {
      throw Exception('User not authenticated');
    }
    try {
      final querySnapshot = await FirebaseFirestore.instance
          .collection('Document')
          .where('group_ids', arrayContains: groupId)
          .get();

      return querySnapshot.docs.map((doc) {
        final data = doc.data();
        return Documents(
          ...
        );
      }).toList();
    } catch (e) {
      throw Exception('Error loading the documents: $e');
    }
  }

This is a snippet of my security rules, just like in the doc:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Rule for Document collection
    match /Document/{document} {
      // Allow reads and deletion if the current user owns the existing document
      allow read, delete, get: if request.auth.uid == resource.data.user_id;
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.user_id;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.user_id
                    && request.auth.uid == resource.data.user_id;

    }

I am expecting to load the Documents but instead get the above mentioned Exception.

The Exception occurs no matter if there are any Documents or not. The User UID and the user_id from the Document are the same, but as already mentioned the error occurs even if there are no documents at all. The Document contains fields group_ids and user_id.

I know I can just allow all read and write operations, but I am also looking for a prod solution.


Solution

  • Your rules are demanding that the query correctly filter on field user_id, but your code only filters on group_ids. Since your query doesn't filter on user_id in a way that satisfies the rules' requirements, the rules simply reject access entirely.

    Security rules are not filters (you should read and understand that documentation). Rules will not change the set of resulting documents. Either the query has access to all the requested documents, or none at all, so your query must only request documents that would be allowed by the rules by applying a filter that satisfies the requirements of the rules.