firebase - 如何授予基于其他集合的用户的集合访问权限?
问题描述
假设有 3 个集合并且它们处于相同的层次结构级别:
- 用户
- UserAndOtherCollectionRelationship
- 其他收藏
我希望向拥有该记录或与之相关的用户授予对“OtherCollection”记录的访问权限(仅读取访问权限)。
将“UserAndOtherCollectionRelationship”理解为
UserAndOtherCollectionRelationship: {
'userId': uid, //user id provided by Firebase Auth Service
'otherCollectionId': 000,
'roles': ['owner', 'reader', ...]
}
这就是我所拥有的:
match /databases/{database}/documents {
match /otherCollection/{otherCollectionId} {
allow read, update, delete: if(isOtherCollectionOwner());
allow create: if(isSignedIn());
}
match /user/{userId} {
allow read, write: if(isSignedIn() && isUserOwner(userId));
}
match /userAndOtherCollectionRelationship/{userAndOtherCollectionRelationshipId} {
allow read: if(resource.data.userId == request.auth.uid && isSignedIn());
allow create: if(isSignedIn());
allow update, delete: if(resource.data.userId == request.auth.uid);
}
// Functions
function isSignedIn() {
return request.auth != null;
}
function isUserOwner(userId) {
return request.auth.uid == userId;
}
function isOtherCollectionOwner() {
return isUserOwner(getUserAndOtherCollectionRelationshipData().userId) && getOtherCollectionData().roles.hasAll(['owner']);
}
//This is the function that I believe that it's not working propertly
function getuserAndOtherCollectionRelationshipData() {
return get(/databases/$(database)/documents/userAndOtherCollectionRelationship/{document=**}).data;
}
}
考虑到客户端(应用程序)必须创建一个过滤器(where 子句)来仅获取所需的记录,我也找不到使用此模式的方法。
所以我把用户角色作为一个字段放在“otherCollection”记录上:
otherCollection: {
...,
'userAndRoles': {
'replaceByUID': ['owner', ...]
},
}
将安全规则功能更新为:
function isOtherCollectionOwner() {
return get(/databases/$(database)/documents/OtherCollection/$(otherCollectionId)).data.roles[request.auth.uid].hasAll(['owner']);
}
这是客户电话:
final querySnapshot = await firestore.collection('otherCollection')
.where('user.$userId', arrayContains: 'owner')
.where('otherCollectionId', whereIn: otherCollectionIdList)
.get();
什么是最好的解决方案?将数据模型更改为... 将不同的安全规则设置为...
解决方案
为了解决这个问题,我更新了数据模型,删除了 userAndOtherCollectionRelationship 集合,并将 owner 属性添加到 otherCollection。
任何其他关系都将作为属性添加到 otherCollection。
所以 otherCollection 现在看起来像这样:
otherCollection: {
owner: ["user_uid", "other_user_id"],
..., //other atributes
}
安全规则更新为:
match /otherCollection/{otherCollectionId} {
allow read, update, delete: if(isOtherCollectionOwner());
allow create: if(isSignedIn());
}
function isOtherCollectionOwner() {
return ([request.auth.uid] in (resource.data.owner));
}
安全规则测试已更新为:
const myAuth = {uid: 'my_user_uid', email: 'my@mail.com'};
const MY_PROJECT_ID = "my_project_id";
function getAdminFirestore() {
return firebase.initializeAdminApp({projectId: MY_PROJECT_ID, auth: myAuth}).firestore();
}
function getFirestore(auth) {
return firebase.initializeTestApp({projectId: MY_PROJECT_ID, auth: auth}).firestore();
}
describe("MyApp", () => {
it("Can list if is owner", async () => {
const admin = getAdminFirestore();
const setupOtherCollection = admin.collection('otherCollection').doc('otherCollectionId');
await setupOtherCollection.set({'name': 'myOtherCollection', 'owner': [myAuth.uid]});
const db = getFirestore(myAuth);
const otherCollectionCollection = db.collection("otherCollection").where("owner", "array-contains", [myAuth.uid]);
await firebase.assertSucceeds(otherCollectionCollection.get());
});
});
推荐阅读
- actionscript-3 - 如果在同一位置或碰撞,如何删除同名的孩子?AS3
- python - 如何从python中的日期开始打印前30天,在Tkinter中打印相同的日期
- python - 尽管在模块和主代码中导入了 re,但未定义名称 re
- colorfilter - 去马赛克 RCCB 彩色滤光片阵列
- javascript - 无论光标或焦点在哪里,如何在 10 秒后关闭自动完成菜单?
- javascript - wavesurfer getPeaks 返回一个空数组
- flutter - 将文件上传到 Flutter web 上的 Parse Server
- android - Kotlin - 在活动重启时保留 RecyclerView 位置
- python-3.x - 将核苷酸序列转换为二维整数数组
- vba - 排列形状以使边缘重合 Visio VBA