firebase Firestore事务和批处理?

rqqzpn5f  于 2023-01-31  发布在  其他
关注(0)|答案(1)|浏览(148)

我有一个注册客户端的函数。该函数负责创建用户、用户公司以及添加一些关于用户的 meta数据。然而,该函数的脆弱之处在于,如果其中一个请求失败,用户就会被卡住,无法再次注册。有人告诉我,可以使用事务或批处理来解决这个问题。我研究过writeBatch()和批处理,但您似乎需要引用要更新的文档。然而,在我的情况下,我正在创建新文档-我如何将其重构为事务/批处理?到目前为止,我所拥有的是:

const registerUser = async (user: RegisterUserData) => {
    try {
      const batch = writeBatch(db);

      const test = await runTransaction(db, async (transaction) => {
        const userDoc = await createUserWithEmailAndPassword(auth, user.email, user.password);
        const userId = userDoc.user.uid;

        const companyRef = batch.set(doc(db, 'companies'), {
          title: user.companyName,
          userCount: 1
        });

        let isAdmin = false;
        if (await setUserAsAdmin(userId)) {
          isAdmin = true;
        }

        batch.set(doc(db, 'users'), {
          email: user.email,
          userId: userId,
          firstName: user.firstName,
          lastName: user.lastName,
          isAdmin: isAdmin,
          role: isAdmin ? 'admin' : 'coach',
          clientCount: 0,
          // companyId: companyRef.id
        });
        await batch.commit();
      });
      console.log('test', test)
    } catch (e) {
      console.log('error', e);
      throw new Error('cant register user: ' + e);
    }
  };

重构之前的原始函数如下所示(并且正在工作):

const registerUser = async (user: RegisterUserData) => {
    try {
      const createUser = await createUserWithEmailAndPassword(auth, user.email, user.password);
      const createdCompany = await createUserCompany({
        title: user.companyName,
        userCount: 1
      });
      let isAdmin = false;
      const adminSet = await setUserAsAdmin(createUser.user.uid);
      if (adminSet) {
        isAdmin = true;
      }
      await createUserMetaData({
        email: user.email,
        userId: createUser.user.uid,
        firstName: user.firstName,
        lastName: user.lastName,
        isAdmin: isAdmin,
        role: isAdmin ? 'admin' : 'coach',
        clientCount: 0,
        companyId: createdCompany.id
      });
      return createUser;
    } catch (e) {
      throw new Error('cant register user' + e);
    }
  };
jm81lzqq

jm81lzqq1#

不能在Firestore事务中包含从JS SDK的Auth部分对createUserWithEmailAndPassword()方法的调用,事实上,可以包含在Firestore事务中的原子操作集只能是Firestore操作(请参阅doc以获得确切的列表)。
因此,虽然您可以在批处理写入中包含两个Firestore写入,但不可能在事务中包含用户创建。
如果您希望避免创建用户但不创建Firestore文档的(罕见)情况,一种可能的解决方案是定期检查这种情况,例如使用scheduled Cloud Function来纠正问题。

相关问题