Search code examples
firebasefluttergoogle-cloud-firestorefirebase-security

Cloud Firestore: Problem with rules for my Flutter app


Here are my current Cloud Firestore rules: https://pastebin.com/rQBacfLm

In this screenshot you can see my current database structure:

In this screenshot you can see my current database structure.

Here is the code from my Flutter app with which I am trying to get a stream of the boats in which "owner" equals the users UID:

_databaseReference.collection("boats").where("owner", isEqualTo: "My UID").snapshots()

I have no idea whether there is a general fault in the rules or whether it has something to do with the stream. I think it might be a problem with the rules, but I don't know what is wrong. Can someone spot an error in the rules?

This is the log from the console:

W/Firestore(26299): (22.0.1) [Firestore]: Listen for Query(target=Query(boats where owner == # com.google.firestore.v1.Value@628107b8
W/Firestore(26299): integer_value: 0
W/Firestore(26299): string_value: "My UID" order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
W/Firestore(26299): (22.0.1) [Firestore]: Listen for Query(target=Query(boats where share array_contains # com.google.firestore.v1.Value@628107b8
W/Firestore(26299): integer_value: 0
W/Firestore(26299): string_value: "My UID" order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

Important information: "My UID" is just a placeholder, in reality there is my real UID. That is not the problem!


Solution

  • As you can see in my Firestore rules (https://pastebin.com/rQBacfLm), these are the conditions for accessing documents from the boats collection:

    match /boats/{boat} {
      allow create: if isUser(database);
      allow read, update: if isUser(database) && isShared(boat, database);
      allow read, update, delete: if isUser(database) && isOwner(boat, database);
    }
    

    When I now execute _databaseReference.collection("boats").where("owner", isEqualTo: "My UID"), I get a PERMISSION_DENIED error, because where needs the permission list, which is included in the permission read, but the read permission is only given for boats for which isShared is true. Therefore the list permission needs to be added to the line allow create, so that the app can search for the boats the user owns (.where("owner", isEqualTo: "My UID")).