[Solved] Although I do not write anything, firebase gives permission error

Question

Asked by efesahin on November 02, 2021 (source).

I have an app for my school. There are some features, but they have not functionalities. I mean students or users, do not write anything. They just read posts, they read bus times etc. Although this, firebase gives an error. Firstly I used

allow read write: if true

but I know it is not safe. So What should I do here? I did request.auth != null because you know my app has not any authentication. So users can't write anything. Although this, firebase gives this error:

Status{code=CANCELLED, description=Disconnecting idle stream. Timed out waiting for new targets., cause=null}.

My firebase rules section:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

error message :

W/Firestore( 6365): (23.0.4) [Firestore]: Listen for Query(target=Query(users/h0m3_p4g3_ order by name);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

the code from your app that generates that error: (method_channel_document_reference.dart)

  @override
  Future<DocumentSnapshotPlatform> get(
      [GetOptions options = const GetOptions()]) async {
    try {
      final Map<String, dynamic>? data = await MethodChannelFirebaseFirestore
          .channel
          .invokeMapMethod<String, dynamic>(
        'DocumentReference#get',
        <String, dynamic>{
          'firestore': firestore,
          'reference': this,
          'source': getSourceString(options.source),
        },
      );

      return DocumentSnapshotPlatform(firestore, _pointer.path, data!);
    } catch (e) {
      throw convertPlatformException(e);
    }
  }

here when I start the app, it moves catch part of the this code. Throw convertPlatformException(e);

Answer

Question answered by Ernesto C (source).

Based on the additional information from the comments and your use case, you should first separate read and write access. Your current rules treat both reading and writing under the same condition, even though you only want to restrict writes to Firestore while allowing users to read. The Firestore documentation includes an example of separate write and read access.

Moreover, since your application does not require authentication, read access should be public in some form. The documentation also touches a similar example in which only documents that have public visibility can be read from users. This could be a possible way to enable public access for reading the database. Writing both of these characteristics would result in the following rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow write: if false; //completely blocks access to writing
      allow read: if resource.data.visibility == 'public'; //resource.data comes from requested documents, visibility being a value from the doc
                                                           //only documents with a visibility value of public can be read
    }
  }
}

Firestore rules have many more parameters that can be applied, so a good starting point is the Get Started page. Keep in mind that your Flutter code should specifically implement queries that fit to the rules, since rules are not filters and too general queries will result in denied access:

Once you secure your data and begin to write queries, keep in mind that security rules are not filters. You cannot write a query for all the documents in a collection and expect Cloud Firestore to return only the documents that the current client has permission to access.

FIREBASE FIREBASE-SECURITY FLUTTER GOOGLE-CLOUD-FIRESTORE
SHARE: