我正在使用Web Client SDK v9编写一个基于Cloud Firestore的应用程序(但这是数据库架构的一个更一般的问题,不一定与此特定的SDK相关)。
我想实现以下功能:
- 用户可以创建组
- 用户可以通过发送邀请码邀请其他用户加入他们的群组(应用程序创建一个邀请码,该邀请码将授予对相关群组的访问权限)
- 其他用户可以使用此邀请代码加入组
这就是我希望在安全规则中对邀请/加入组的处理进行建模的方式:
- 只有作为组成员的用户可以读取它
- 只有属于组的用户才能写入它,但以下用户除外:
- 具有有效邀请代码的用户可以将自己作为成员写入组
在Cloud Firestore中对此建模似乎是不可能的。
到目前为止,我有一个集合groups
和另一个集合invites
,invite的邀请代码为doc.id
,字段groupId
中有它将授予访问权限的组的id。
我发现一般有两种方法可以对组成员身份进行建模,但似乎这些方法都不允许对上述安全规则进行建模:
A)组具有子集合members
,具有有效邀请码的用户可以将他们自己添加到该子集合。
match /groups/{groupID} {
function hasValidInvite() {
return exists(/databases/$(database)/documents/invites/$(request.resource.data.inviteCode));
}
match /members/{memberID} {
allow write: if hasValidInvite();
}
}
所以写成员资格是可行的,但是查询一个用户的所有成员资格似乎是不可能的,因为集合查询不能在子集合上执行where(documentId(), "==", getAuth().currentUser.uid)
(这似乎是一些bug)。
鉴于此问题,建议采用第二种方法:
B)一个组有一个数组字段members
,用户id被写入其中。我只需要检查当前的uid
是否在组的members
数组中。但是我发现没有办法编写安全规则来允许某人只在arrayUnion()
字段上并且只对组执行arrayUnion()
操作他们拥有的有效邀请。
所以我有两种非常不同的方法,每种方法都涵盖了解决方案的一半,但不兼容。
你知道我该怎么做吗?
1条答案
按热度按时间p1iqtdky1#
事实证明,这两种解决方案可以在云函数的帮助下结合起来,该函数侦听对
members
集合中文档的更改,并将新创建文档的id
写入相应groups
文档中的members
数组:缺点: