【问题标题】:Cloud Functions for Firebase: how to use a Transaction promise?Firebase 的云功能:如何使用交易承诺?
【发布时间】:2018-05-24 19:00:29
【问题描述】:

我正在尝试在 Cloud Functions 中编写一个函数,该函数在每次创建用户时触发,然后将该用户保存到用户列表中,最后增加用户计数器。 但是我不确定我是否正确使用了 Promise。

exports.saveUser = functions.auth.user().onCreate(event => {
    
   const userId = event.data.uid
  
   const saveUserToListPromise = db.collection("users").doc(userId).set({
      "userId" : userId
   })
   
   var userCounterRef = db.collection("users").doc("userCounter");
   
   const transactionPromise = db.runTransaction(t => {
      return t.get(userCounterRef)
          .then(doc => {
              // Add one user to the userCounter
              var newUserCounter = doc.data().userCounter + 1;
              t.update(userCounterRef, { userCounter: newUserCounter });
          });
  })
  .then(result => {
      console.log('Transaction success!');
  })
  .catch(err => {
      console.log('Transaction failure:', err);
  });
  
  return Promise.all([saveUserToListPromise, transactionPromise])

})

我想确保即使有很多用户同时注册,我的 userCounter 仍然正确,并且 saveUser 函数不会在事务和保存到列表发生之前终止。

所以我尝试了这个,它工作得很好,但是我不知道这是否是实现我想要的功能的正确方法,我也不知道当实际上有很多用户触发时这是否仍然有效立即使用该功能。

希望你能帮助我。 提前致谢。

【问题讨论】:

    标签: javascript node.js firebase google-cloud-functions google-cloud-firestore


    【解决方案1】:

    transaction 中以原子方式执行多个写入的正确方法是在事务块内使用Transaction 对象(此处为t)执行所有写入。这样可以确保所有写入都成功,或者不成功。

    exports.saveUser = functions.auth.user().onCreate(event => {
        const userId = event.data.uid
        return db.runTransaction(t => {
            const userCounterRef = db.collection("users").doc("userCounter")
            return t.get(userCounterRef).then(doc => {
                // Add one user to the userCounter
                t.update(userCounterRef, { userCounter: FirebaseFirestore.FieldValue.increment(1) })
                // And update the user's own doc
                const userDoc = db.collection("users").doc(userId)
                t.set(userDoc, { "userId" : userId })
            })
        })
        .then(result => {
            console.info('Transaction success!')
        })
        .catch(err => {
            console.error('Transaction failure:', err)
        })
    })
    

    【讨论】:

    • 啊,好的,谢谢。看起来是一种更清洁、更“安全”的做事方式。
    • 如何在 typescript 中编写事务(与上述实现相同)。
    • 所有 JavaScript 都是有效的 TypeScript,因此您可以完全按照所示复制它。 @ArulManivannan
    • @DougStevenson 这段代码会为实时数据库运行吗?
    • ^ 如果我将其用于 firebase 实时数据库,则会收到“TypeError: t.get is not a function”
    猜你喜欢
    • 2023-04-01
    • 2018-04-19
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2014-05-22
    • 2017-09-25
    相关资源
    最近更新 更多