Cloud Functions for Firebase:如何使用事务承诺?

Max*_*Max 5 javascript node.js firebase google-cloud-functions google-cloud-firestore

我正在尝试在 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])

})
Run Code Online (Sandbox Code Playgroud)

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

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

希望您能够帮助我。提前致谢。

Dou*_*son 7

事务中以原子方式执行多次写入的正确方法是使用事务块内的事务对象(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)
    })
})
Run Code Online (Sandbox Code Playgroud)