Google cloud firestore Firestore安全规则get()不工作

Google cloud firestore Firestore安全规则get()不工作,google-cloud-firestore,firebase-security,Google Cloud Firestore,Firebase Security,在firestore中,我希望用户仅在文档中提到的teamid中访问文档。现在我有一个名为teams的不同集合,其中用户映射为{user\u id=true}。所以我在Firestore规则中有以下内容 return get(/databases/$(database)/documents/teams/$(resource.data.teamid)).data.approvedMembers[request.auth.uid] == true; 现在,此规则不起作用,前端对数据库的任何请求都会

在firestore中,我希望用户仅在文档中提到的
teamid
中访问文档。现在我有一个名为
teams
的不同集合,其中用户映射为
{user\u id=true}
。所以我在Firestore规则中有以下内容

return get(/databases/$(database)/documents/teams/$(resource.data.teamid)).data.approvedMembers[request.auth.uid] == true;
现在,此规则不起作用,前端对数据库的任何请求都会失败。但当我用实际的
teamid
值替换
$(resource.data.teamid)
时,如下所示

return get(/databases/$(database)/documents/teams/234234jk2jk34j23).data.approvedMembers[request.auth.uid] == true;
。。。它按预期工作

现在我的问题是,我是否以错误的方式使用
资源
,或者在Firestore规则中的
get()
exists()
查询中不支持
资源

编辑 完成以下规则

service cloud.firestore {
  match /databases/{database}/documents {

    function isTeamMember() {
        return get(/databases/$(database)/documents/teams/$(resource.data.teamid)).data.approvedMembers[request.auth.uid] == true;
        // return exists(/databases/$(database)/documents/teams/$(resource.data.teamid));
    }

    match /{document=**} {
        allow read, write: if isTeamMember();
    }
  }
}

如果您注意到注释掉的规则,
exists()
在这种情况下也不起作用。

您有一个匹配的

match /{document=**} {
    allow read, write: if isTeamMember();
}

这将匹配数据库中的任何文档。这意味着当您调用
isTeamMember()
时,不能保证
resource
代表
团队
文档。如果您在
团队中有任何子集合
并向这些子集合写信,则
资源
将成为子集合文档。

感谢您在Twitter上联系。在我们的交谈之后,以下是结论:

使用安全规则查询文档 不能将安全规则用作筛选器。要使其正常工作,还必须添加
。其中('teamid','==',yourTeamId)

您已经确认这对您有效,但您并不总是希望限制一个teamid

使用自定义声明 您可以在身份验证令牌中设置自定义声明。下面是一个如何设置这些规则并在规则中使用它们的示例

设置自定义声明 为此,您需要使用AdminSDK

auth = firebase.auth();

const userId = 'exampleUserId';
const customClaims = {teams: {myTeam1: true, myTeam2: true}};

return auth.setCustomUserClaims(userId, customClaims)
  .then(() => {
    console.log('Custom claim created');
    return auth.getUser(userId);
  })
  .then(userRecord => {
    console.log(`name: ${userRecord.displayName}`);
    console.log(`emailVerified: ${userRecord.emailVerified}`);
    console.log(`email: ${userRecord.email}`);
    console.log(`emailVerified: ${userRecord.emailVerified}`);
    console.log(`phoneNumber: ${userRecord.phoneNumber}`);
    console.log(`photoURL: ${userRecord.photoURL}`);
    console.log(`disabled: ${userRecord.disabled}`);
    console.log(`customClaims: ${JSON.stringify(userRecord.customClaims)}`);
  })
  .catch(err => {
    console.error(err);
  });
应用安全规则
我仍然不能100%确定这是否也需要您按
teamid
进行筛选。请测试并反馈。

您是对集合中的多个文档执行查询,还是提取单个文档?嘿@Toddkerpman。是的,我正在查询多个文档。您能否显示更多规则,包括适用的
match
allow get
语句?@SamStern我在问题中添加了完整的规则
isTeamMember()
将对每个文档运行。但这是我们的初衷。它只需要访问请求资源中的
teamid
。现在,我们已经有意识地决定在每个集合和子集合的每个文档中包含
teamid
,每个集合中的每个文档都有
teamid
。那么查询不应该起作用吗?
allow read, write: if request.auth.token.teams.$(resource.data.teamId) == true;