最近对 Firestore 的哪些更改使其抱怨 "Overlapping recursive wildcard match statement"?

What recent change to Firestore makes it complain about "Overlapping recursive wildcard match statement"?

今天我注意到我无法部署我的 Firestore 规则,尽管它们到目前为止工作正常并且我没有更改它们。这是它不喜欢的部分的摘录:

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

在实践中,这些规则正如我想象的那样奏效了。允许管理员读取非管理员无法直接查询的集合。但是,现在我在部署期间收到此错误:

Error: Compilation error in firestore.rules:

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

我不太明白这里的问题。你会如何解决这个问题?

如果您将规则粘贴到 firebase 控制台中,您可以获得更多信息...

可以看到图片中的错误:

我在存储规则中遇到了同样的问题...当您删除通配符匹配项或所有其他没有通配符的匹配项时,错误消失...但仍在尝试从 google 到理解这个变化...

更新: 进一步调查后,我注意到这个问题出现在所有规则(数据库和存储规则)中。我尝试了 firebase 自己的 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
     }
   }
 }
}

嗯,对于 firebase 自己的示例,规则验证器也失败了......

所以这要么是一个没有记录的新功能,要么是一个错误。

显然不再允许重叠递归规则,而 Firestore 以前可以接受它们。

我通过将管理规则与其他规则合并在一起解决了这个问题。这创建了很多额外的行,因为我有 25 个以上集合的规则,但至少我可以再次部署。

所以这就是上面截断的解决方法:

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

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

(这里是 Google 员工) This is a mistake on our part。我们正在向规则中添加新的编译器 警告,以帮助您注意到可能引入的错误。许多人没有意识到,如果您有多个 match 语句匹配特定路径,那么来自这些块的规则将 OR'ed 放在一起。此警告应该可以帮助您发现这一点。

但是,如果您了解自己在做什么,这绝不是为了阻止您部署有效规则!我们会解决这个问题。


更新 8/1 @11:50am PST

我们在此处进行两项更改:

  • 我们正在发布 4.0.2 版本的 CLI (npm firebase-tools),并修复了此问题,使警告不再致命。这应该会立即发生。
  • 我们将把服务器行为更改为 undo/clarify 这种行为,直到我们做对为止。