Firestore安全规则get()无法正常工作

时间:2018-03-14 10:39:55

标签: google-cloud-firestore firebase-security-rules

在firestore中,如果用户位于文档中提到的teamid,我希望用户只访问文档。现在我有一个名为teams的不同集合,我将用户映射为{ user_id = true }。所以我在Firestore规则中有以下内容

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

现在这个规则不起作用,并且前端对数据库的任何请求都失败了。但是当我将$(resource.data.teamid)替换为我的实际teamid值时,如下所示,

return get(/databases/$(database)/documents/teams/234234jk2jk34j23).data.approvedMembers[request.auth.uid] == true;

......它按预期工作。

现在我的问题是我是以错误的方式使用resource还是在{$ 1}}或resource的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(); } } } 在这种情况下也不起作用。

2 个答案:

答案 0 :(得分:2)

感谢您在Twitter上与我们联系。在我们聊天之后,结论如下:

使用安全规则查询文档

您不能将安全规则用作过滤器。要使其生效,您还必须添加.where('teamid', '==', yourTeamId)

您已确认这适用于您,但您并不总是希望限制一个队友

使用自定义声明

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

设置自定义声明

您需要使用Admin SDK。

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

应用安全规则

allow read, write: if request.auth.token.teams.$(resource.data.teamId) == true;

我仍然不能100%确定这不会要求您按teamid进行过滤。请测试并反馈。

答案 1 :(得分:1)

你有match

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

这将匹配数据库中的任何文档。这意味着当您致电isTeamMember()时,我们无法保证resource代表team文件。如果您在teams上有任何子集并写入,则resource将成为子集合文档。