Firebase查询返回“0”;“拒绝许可”;但规则在测试控制台中起作用
我有以下Firebase规则: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
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
。但是,您的规则不允许这样做,原因有二:
get()
。虽然这适用于从客户端获取的单个文档,但不适用于可能返回任意数量文档的查询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;
}