Firebase查询返回“0”;“拒绝许可”;但规则在测试控制台中起作用

Firebase查询返回“0”;“拒绝许可”;但规则在测试控制台中起作用,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,我有以下Firebase规则: match /PendingInvites/{inviteID} { allow read: if request.auth != null && isInviteForUser(database, inviteID); } 以及以下功能: function isInviteForUser(database, inviteID) { let dataItem = get(/databases/$(dat

我有以下Firebase规则:

match /PendingInvites/{inviteID} {
    allow read: if request.auth != null && 
        isInviteForUser(database, inviteID);
}
以及以下功能:

  function isInviteForUser(database, inviteID) {
  
    let dataItem = get(/databases/$(database)/documents/PendingInvites/$(inviteID)).data;
  
    return (dataItem.userPhone == request.auth.token.phone_number) ||
                    (dataItem.userEmail == request.auth.token.email);
  }
使用在线角色测试对集合进行测试是有效的,我已经使用真实文档以及userPhone和userEmail值(匹配和不匹配)进行了验证。所有这些都按预期工作,拒绝不匹配的值并允许匹配的值

这就是它变得奇怪的地方。当我运行此(Android)查询时:

我得到“权限被拒绝:缺少或权限不足”。就我所了解的规则而言,我认为它应该有效。它在在线控制台中工作,我专门查询userPhone(或userEmail),但它不工作

我已经尝试删除userEmail并只测试userPhone,但这似乎也不起作用

有什么想法可以纠正规则(或查询)

谢谢

文件:

测试中使用的身份验证令牌:

{
  "uid": "",
  "token": {
    "sub": "",
    "aud": "certifly-global",
    "phone_number": "+16505551234",
    "firebase": {
      "sign_in_provider": "phone"
    }
  }
}


注意文档如何同时包含用户电话和用户电子邮件

您的规则每次都拒绝查询,因为。请务必阅读该文档和

您的查询要求使用PendingVites中的所有文档,其中
userPhone==+1650551234
。但是,您的规则不允许这样做,原因有二:

  • 您的查询与规则的约束不匹配(userPhone和userEmail都设置为特定值)。查询只是指定userPhone
  • 系统不会对每个可能匹配的文档执行
    get()
    。虽然这适用于从客户端获取的单个文档,但不适用于可能返回任意数量文档的查询
  • 因此,您必须解决这两个问题

  • 根据您的规则,您的查询需要同时使用userPhone和userEmail进行过滤。这意味着您必须在userEmail上添加另一个符合规则要求的
    whereEqualTo
    。换句话说,客户端应用程序需要在该过滤器中传递用户的电子邮件

  • 在规则中根本不需要使用
    get()
    。您可以通过
    resource.data
    引用当前集合中文档中的字段

  • 规则也需要类似的东西:

    match /PendingInvites/{inviteID} {
        allow read: if
            request.auth != null && 
            resource.data.userPhone == request.auth.token.phone_number &&
            resource.data.userEmail == request.auth.token.email;
    }
    

    请在Firestore中显示数据+您正在测试此项的用户的令牌详细信息。添加了上述内容,上述内容在测试控制台中工作。对于快速答案,您的回答是正确的,因为查询是错误的,并且需要两个值(我已修复该问题,但粘贴了错误的值(已编辑))。你建议的规则是好的,只是它有我正试图解决的问题。我的问题是邀请可以有电子邮件或电话,或者两者都有(其目的是匹配用户令牌包含的内容)。如果我包含一个值或另一个值,但同时提供这两个值失败,则查询会起作用,因为文档同时包含这两个值,而令牌只有一个值。这有意义吗?如果您需要电子邮件或电话,请使用逻辑OR运算符,而不是逻辑and。只要我像以前一样使用两个查询(一个用于电话,一个用于电子邮件),这似乎是可行的。看起来你建议的规则很神奇。我最初的规则使用了get()(也使用了OR),但这肯定是不正确的。你能解释一下原因吗(只是出于好奇和对未来的了解)?我相信我在回答中解释了为什么get()不起作用。所以基本上,resources.data是结果集中的文档记录,对的因此,当您需要引用与文档(规则)路径不同的文档时,将使用get();对的
    match /PendingInvites/{inviteID} {
        allow read: if
            request.auth != null && 
            resource.data.userPhone == request.auth.token.phone_number &&
            resource.data.userEmail == request.auth.token.email;
    }