Firebase的云功能:如何使用交易承诺?

时间:2017-12-11 09:30:47

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

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

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函数并且保存到列表中。

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

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

1 个答案:

答案 0 :(得分: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
            var newUserCounter = doc.data().userCounter + 1
            t.update(userCounterRef, { userCounter: newUserCounter })
            // 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)
    })
})