1

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);

alperefesahin
  • 604
  • 6
  • 22
  • Where do you get that error from, and what's make you think it's related to permissions? It looks like a harmless "I'm disconnecting because you're not doing anything with me" type of alert. – Frank van Puffelen Nov 02 '21 at 20:09
  • When I start app with request.auth != null permission, it gives directly permission error. Where do I know it is permission error, debug console gives this: PERMISSION_DENIED: Missing or insufficient permissions @FrankvanPuffelen – alperefesahin Nov 02 '21 at 20:32
  • Can you edit your question to show: 1) **that** error message, and the stack trace for it? 2) the code from your app that generates that error? – Frank van Puffelen Nov 02 '21 at 21:27
  • @FrankvanPuffelen I have added them – alperefesahin Nov 03 '21 at 06:55
  • If I understand correctly your code doesn't sign the user in. So it'd make sense then that ` allow read, write: if request.auth ;` rejects those reads, doesn't it? – Frank van Puffelen Nov 03 '21 at 14:48
  • @FrankvanPuffelen yes. My app has not any signin in proccess. They just click the app and read somethings without login. But although this, it gives an error... – alperefesahin Nov 03 '21 at 14:52
  • Well... `if request.auth != null` means the user has to be signed in. So if you don't sign then in in your app, it is expected that they get denied access. – Frank van Puffelen Nov 03 '21 at 15:22
  • what should I use instead of this? I do not want to use any sign in method. They are able to read the data with their eyes :p – alperefesahin Nov 03 '21 at 15:24
  • Please read your question again and clarify as it's become quite messy. It currently starts with "Although I do not write anything, firebase gives permission error", which by now I think we can explain from your rules and code. The original `Status{code=CANCELLED,` message you had in there, seems unrelated to the question too. What is it that you're actually asking from us now? If you want to know how to secure *your* database, this might be a good place to start: https://stackoverflow.com/questions/69404979/what-security-rules-should-be-applied-to-reads-in-firebase/69407457#69407457 – Frank van Puffelen Nov 03 '21 at 17:14

1 Answers1

1

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.

ErnestoC
  • 2,660
  • 1
  • 6
  • 19
  • how can i set resource.data.visibility ? I mean I use streambuilder and I do not know how can i set this property – alperefesahin Nov 04 '21 at 14:39
  • The `visibility` flag is an example from the [documentation](https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation), which uses an existing document property to validate querying data. You can implement any alternative property to signal if a document is for public viewing if you choose. As to how to update documents from Flutter, the [FlutterFire docs](https://firebase.flutter.dev/docs/firestore/usage#updating-documents) describes how you can use the `update` method to update existing documents. – ErnestoC Nov 04 '21 at 17:22
  • 1
    can you suggest somethings for me? cuz I can't get it. I do not know how can i reach visibility property. You wrote use any alternative property, so what should i do? Can't I do allow read: if public; – alperefesahin Nov 04 '21 at 17:29
  • maybe I can do allow read: if true; Can I ? – alperefesahin Nov 04 '21 at 17:31
  • 1
    If **all** of the documents in your database are for public viewing, then `allow read: if true;` could be used. The important part according to your use case is leaving `allow write: if false;` so that no users are able to modify the database. – ErnestoC Nov 04 '21 at 18:36
  • that's the point. Everything is okay now.. – alperefesahin Nov 04 '21 at 19:14