8

Today I noticed that I am unable to deploy my Firestore rules, even though they worked fine until now and I didn't change them. Here's an excerpt of the part it doesn't like:

match /databases/{database}/documents {

    function userMatchesId(userId) {
      return request.auth != null
          && request.auth.uid == userId
    }

    function userIsAdmin() {
      return request.auth != null
          && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "admin"
    }

    // === Admins ====
    // Admin users are allowed to access everythings.
    // Writes should be performed via code executed by a service account
    match /{document=**} {
      allow read: if userIsAdmin()
    }

    // ==== Private ====
    // Collections private to the user. Documents read access is matched
    // with the authenticated user id.
    match /users/{userId} {
      allow get: if userMatchesId(userId)
    }

    match /userCredits/{userId} {
      allow get: if userMatchesId(userId)
    }
}

In practice these rules have worked as I imagined it. Admins are allowed to read from collections that non-admins are not able to query directly. However, now I get this error during deployment:

Error: Compilation error in firestore.rules:

[W] 42:5 - Overlapping recursive wildcard match statement.

I do not quite understand the issue here. How would you fix this?

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Thijs Koerselman
  • 21,680
  • 22
  • 74
  • 108

3 Answers3

6

(Googler here) This is a mistake on our part. We are adding new compiler warnings to rules that help you notice bugs you may be introducing. Many people don't realize that if you have more than one match statement that matches a particular path, then the rules from those blocks are OR'ed together. This warning was supposed to help you discover that.

However it was never intended for this to stop you from deploying valid rules if you understand what you're doing! We will fix this.


Update 8/1 @ 11:50am PST

We are making two changes here:

  • We are releasing the CLI (npm firebase-tools) at version 4.0.2 with a fix for this issue to make warnings non-fatal. This should happen momentarily.
  • We are going to change the server behavior to undo/clarify this behavior until we get it right.
Sam Stern
  • 24,624
  • 13
  • 93
  • 124
3

You can get more information if you paste your rules in the firebase console...

You can see the error in the picture:

enter image description here

I had the same problem in my storage rules... when you remove wildcard match or all other matches without the wildcard, error goes away... But still trying to find a document from google to understand this change...

Update: After investigating further I noticed this problem is occurring in all rules (db and storage rules). I tried firebase's own example for wildcards from this link:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Well, rules validator is failing for firebase's own example as well...

enter image description here

so this is either a new feature that's not documented or a bug.

Nooneelse
  • 127
  • 2
  • 11
  • 1
    I don't see how this gives me more info. The cli already reports where the error is (42:5), which points to that line in my rules. And the error message is the same. I was wrong to assume that it came from firebase-tools. The error comes from Firestore in general, and there is no way I can deploy now by rolling back library versions :-\ I will change the title/question – Thijs Koerselman Aug 01 '18 at 10:44
  • It doesn't but you can get realtime feedback from gui when you change your rules... – Nooneelse Aug 01 '18 at 10:48
  • But I really need the wildcard. Removing it is not an option :-) Ok I will play with it some more and see what I can come up with – Thijs Koerselman Aug 01 '18 at 10:56
  • 1
    I think this is a bug on google's end... OR they changed something and didn't update the documentations. **Even the wildcard examples from their documentations are giving this error.** I tried this full example in storage rules and still getting same error... (link: https://firebase.google.com/docs/storage/security/secure-files ) – Nooneelse Aug 01 '18 at 11:00
  • 1
    Thanks for looking into that! That is quite a mess-up then I managed to solve my case at least by merging my wildcard rules with the others. – Thijs Koerselman Aug 01 '18 at 11:25
0

Apparently overlapping recursive rules are not allowed anymore where Firestore was fine with them before.

I solved it by merging the admin rules together with the others. This created a lot of extra lines, since I have rules for 25+ collections, but at least I can deploy again.

So this is how it would be solved for the snipped above:

 match /users/{userId} {
  allow get: if userMatchesId(userId)
  allow read: if userIsAdmin()
}

match /userCredits/{userId} {
  allow get: if userMatchesId(userId)
  allow read: if userIsAdmin()
}
Thijs Koerselman
  • 21,680
  • 22
  • 74
  • 108
  • For DB side you can write rules for each collection but in a storage defining rules for every folder might be hard... you might want to say admin reads all 1000 folder while users can only read their own folders or a special folder. – Nooneelse Aug 01 '18 at 11:27
  • True. So that would indicate that this might be a bug rather then a new stricter feature set, but I'd expect this to affect a lot of users. – Thijs Koerselman Aug 01 '18 at 13:07