我有一个 Angular Web 应用,使用 Firebase 作为无服务器后端技术。该网络应用程序的当前目的是让注册用户为所提供的产品创建文档。虽然商业用户可以创建无限的产品文档,但免费用户应该只能创建一个产品文档。
收藏:
- 用户 -
{id:字符串,isBusiness: bool 值,名称:字符串,电子邮件:字符串,productIds:字符串[]}
- 产品 -
{id:字符串,标题:字符串,描述:字符串,userId:字符串}
每当用户创建新的产品文档时
public createProduct(id: string, product: Product) {
return this.afStore.collection('products').doc(id).set(product, { merge: true });
}
我使用触发器 onCreate
运行云函数,将创建的产品文档的 id
添加到相应的 productIds
字段中用户文档。这使我可以检查前端 if(!user.isBusiness && ProductIds.length > 1)
以限制为免费用户帐户创建多个产品文档。
但是,我最近做了一次笔测试,测试人员偶然发现,如果您在多个浏览器选项卡上打开网站,并同时在每个选项卡上运行 createProduct()
函数,所有这些都将执行,允许非业务用户拥有多个产品文档。
有人遇到过类似的情况吗?我不知道是否有办法通过 Firestore 安全规则来避免这种情况,或者是否需要等待事件事务完成。
最佳答案
当前的实现存在竞争条件:“非业务”用户可以创建任意数量的产品,直到第一个 ProductId 写入用户文档。
在我看来,解决这个问题最直接的方法是为非业务用户预先填充一个productId,并限制他们分配新产品的能力。
- 创建非业务用户后,您可以为他们创建/保留一个唯一的productId,他们可能会使用也可能不会使用该产品ID。将其存储在用户文档中。
- 非业务用户创建产品时,只能将数据写入该产品 ID。虽然不需要修复所描述的用例,但根据您的安全要求,您可能希望通过安全规则或云功能来强制执行此操作。
- 无论有多少个并发选项卡尝试创建产品,它们始终会写入相同的productId。
public createProduct(id: string, product: Product, user: User) {
if (user.isBusiness) {
return this.afStore.collection('products').doc(id).set(product, { merge: true });
} else {
return this.afStore.collection('products').doc(user.reservedProductId).set(product, { merge: true });
}
}
警告:与任何前端代码一样,这不会阻止恶意行为者按照自己的喜好操纵它。如果此行为存在安全问题,您将需要限制非业务用户对产品集合的写访问。考虑实现适当的安全规则/云功能。您只能信任后端。
关于angular - Firebase Firestore - 限制用户可以创建的产品文档数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65158299/