如何在firebase firestore中保护用户访问数组?



在我的angular firebase应用程序中,许多用户可以登录并编辑同一个数据。例如,假设他们正在编辑特定主题的文档。每天都会生成一个新的Report对象,它继承不同的主题和文档。我的数据结构如下:

export interface Report {
date: Date;
day: string;
topics: Topic[];
}
export interface Topic {
name: string;
documentations: Documentation[];
}
export interface Documentation {
userId: string;
userName: string;
documentation: string;
}

我想将报告存储为一个没有子集合的对象,这样我就可以一次加载所有数据,而不必向API发出大量的读请求。此外,我的用户被分成不同的组,所以一个报告每个主题最多只能有4个文档,大约6到10个主题。

因此每个用户都可以阅读其他用户的文档,但应该只能编辑自己的文档。据我所知,通过Firestore安全规则来保护对数组的访问是不可能的,所以我唯一不可能的是使用云功能来保护我的数据。但我不知道,这是最有效的方法还是另一种数据结构更适合我的情况。因此,如果我是对的,我必须使用云功能,我如何检查,如果用户只编辑了他的文档,而所有其他未编辑的?或者我应该尝试不同的方法?

如果每个用户都可以编写自己的文档,那么正确的数据模型不是数组,而是作者的UID到他们编写的文档的映射:

documentations: Map<String, Documentation>;

既然您现在知道了每个用户被允许修改的数据的密钥,这也使您更接近于能够保护它。我只是觉得你可能还是会被困住,因为我不确定你是否能写一个"适用于所有用户"的规则。


如果将特定于用户的数据放在文档的子集合中,这样的数据结构问题通常更容易解决。

这可能就是我对它的建模方式,然后使用Cloud Function将子集合中的数据聚合回父文档中,以仍然满足您只需要读取单个文档即可获得所有用户贡献的要求。

我仍然会使用上面提到的模型,因为这样可以确保您可以使用单个(幂等)写入来执行聚合,而不必首先读取父文档以检查用户是否已经对其进行了贡献。

如果您正在使用Cloud函数,那么您可以简单地读取该文档,检查该数组,比较用户UID并检查用户是否只编辑他们的文档,然后更新整个文档。

exports.addMessage = functions.https.onCall((data, context) => {
const {uid} = context.auth
const {updates, documentationId, reportId} = data
// 1. Fetch document using reportId
// 2. Read the documentations array
// 3. Check if doc with that ID exists and if caller owns it
// 4. If yes, update else return 403 - forbidden error 
});

相关内容

  • 没有找到相关文章

最新更新