在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();
}
}
}
在这种情况下也不起作用。
答案 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
将成为子集合文档。