首页 > 解决方案 > Firebase 实时数据库 - 多组访问?

问题描述

我目前有一个类似于以下的数据库结构。如果无法在 Firebase 实时数据库安全规则中循环,我如何根据用户访问多个组来保护数据?要遵循的示例...

数据库结构:

// list of different groups a user can belong to.
// they can belong to multiple groups.

"userGroups": {
  "groupA": ...
  "groupB": ...
  "groupC": ...
}

// each user has a list of group ids they belong to

"users": {
  "userA": {
    groups: ['groupA', 'groupB'],
  },
  "userB": {
    groups: ['groupB'],
  }
}

// various nodes in the database an admin sets restriction on content
// so specific data can only be access by specified group

"someFunData": {
  "data1": {
    authorisedGroups: ['groupA', 'groupB'],
  },
  "data2": {
    authorisedGroups: ['groupB'],
  }
}

如何指定安全规则以根据当前用户someFunData指定的任何组之间的匹配来限制它?someFunData/$dataId/authorisedGroupsgroups

标签: firebasefirebase-realtime-databasefirebase-security

解决方案


首先,userGroups可能会产生误导。它可能意味着“每个用户的组”。如果您没有任何其他类型的组,则可以将其称为groups.

在类似的场景中,我为影响用户应该看到的每条路径创建了一个云函数。

const updateUserFunData = (path: string) => {
    return functions.database.ref(path).onWrite(async (data, context) => {
        // Download any required data, calculate what changes should be made,
        // then use a multi-path update to save these changes, like this:
        await rootRef.child('userFunData').update({
            [uid1 + '/' + data1]: true, // or a complete copy of the data
            [uid1 + '/' + data2]: null, // use null to delete
        });
    });
};
export const onUserGroupsChange = updateUserFunData('users/{uid}/groups');
export const onFunDataGroupsChange = updateUserFunData('someFunData/{dataId}/groups');

然后客户端可以读取userFunData/$uid以获取他们的数据 ID(然后获取每个funData),并且规则可以检查是否userFunData/$uid/$dataId存在,以允许或拒绝读取。

如果您想跳过该中间 funData IDs 查询和所有以下查询的同步,您可以替换true为数据的完整副本,为应该更改该数据的其他数据库更改添加触发器,并让客户端仅查询userFunData/$uid,其中应该包含他们应该看到的所有数据。


您评论说维护每个用户的数据列表是不切实际的。您可以维护每个组的数据列表,并让每个用户获取每个组的数据。规则将检查用户是否存在于正在读取的组的用户中。您必须将每个组的用户(或每个用户的组)保存为地图而不是数组。


推荐阅读