next.js Firebase -防止用户注册时出现竞争条件

798qvoo8  于 2023-04-20  发布在  其他
关注(0)|答案(2)|浏览(103)

我有一个Firebase/Next.js应用程序,我正在工作,通过Firebase托管部署。
在这个应用程序中,我试图实现一个与用户注册相关的功能。当用户注册一个帐户时,用户将获得一个包含其数据的文档。文档中的一个字段是帐号。对于这个特定的应用程序,我希望帐号对每个帐户按创建顺序递增1。例如,第一个用户的帐号为1,下一个有2,以此类推。
我通常会创建一个Next.js API路由来实现类似的东西。该API将验证用户的令牌,从凡士通读取现有用户的数量,最后为用户创建一个文档。
如果API只被一个用户使用,这将起作用,如果多个用户同时调用API,则会出现竞争条件。

- Server has 3 users
Alice : Reads the number of current users (3)
Bob : Reads the number of current users (3)
Bob : Creates user #4
Alice : Creates user #4
- Server has 5 users, Alice and Bob are both user #4

看起来我需要做的是有一种方法来排队这些请求,比如每个API调用添加一个请求到队列中,一旦到达就解决。在实践中,我不确定实现这样的东西会是什么样子。
一个简单的方法是每秒运行一个云函数,它从队列中读取,创建用户,然后从队列中删除请求。虽然这样做是可行的,但它是浪费和低效的。
有没有一种方法可以在Firebase中有效地完成这样的事情?

cgvd09ve

cgvd09ve1#

我看到的最简单的解决方案是在Firestore中的文档内创建一个计数器字段,该字段可以在每次用户创建时递增。实现该功能的步骤如下:
1.在Firebase中创建用户之前,部署并注册一个阻塞函数。

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  const count = admin.firestore().collection('users').count();
});

如您所见,为了统计用户数量,我使用了count()函数。
1.一旦创建了用户,您就可以创建另一个函数来执行两个Firestore操作。一个是使用计数器的值将用户数据写入Firestore,另一个是递增计数器的值。

exports.writeDataToFirestore = functions.auth.user().onCreate((user) => {
  // Code to write user data and update the counter.
});

因为你执行了两个操作,所以你可以在一个批处理中执行它们。请注意,一个批处理操作是原子地完成的。此外,当你增加计数器时,不需要一个事务,你可以简单地增加值。后一个操作也是原子的,所以你不可能有两个用户具有相同的计数。除此之外,也不需要每秒运行一个云函数。

kcrjzv8t

kcrjzv8t2#

我不是Maven和新的android应用程序开发.但你的应用程序索引的文档符合我的想法.我在几个论坛,我的结论是索引文档增量1不是一个很好的主意,你可能会得到重复的id(index)进行并发日志记录。而应该使用push()函数,生成一个唯一的key。这可以生成一个类似于MongoDB文档的唯一id。请参考firebase文档这里的unique key gen。当然,你可以用transaction操作做增量计数器来承担风险,实现后希望你反馈一下效率,因为我也是用firebase数据库的。

相关问题