Javascript Firebase:具有异步/等待的事务

Javascript Firebase:具有异步/等待的事务,javascript,firebase,google-cloud-firestore,Javascript,Firebase,Google Cloud Firestore,我正在尝试对事务使用async/Wait。 但是获取错误“参数”updateFunction“不是有效的函数。” 重要提示:正如一些用户所指出的,此解决方案无法正确使用事务。它只是使用事务获取文档,但是更新在事务之外运行 检查alsky的答案 看看文档,runTransaction必须接收updateFunction函数作为参数。() 试试这个 var docRef = admin.firestore().collection("docs").doc(docId); let doc = awa

我正在尝试对事务使用async/Wait。 但是获取错误“参数”updateFunction“不是有效的函数。”


重要提示:正如一些用户所指出的,此解决方案无法正确使用事务。它只是使用事务获取文档,但是更新在事务之外运行

检查alsky的答案



看看文档,runTransaction必须接收updateFunction函数作为参数。()

试试这个

var docRef = admin.firestore().collection("docs").doc(docId);
let doc = await admin.firestore().runTransaction(t => t.get(docRef));

if (!doc.exists) {throw ("doc not found");}
var newLikes = doc.data().likes + 1;

await doc.ref.update({ likes: newLikes });

上述内容对我不起作用,并导致此错误:“[错误:在事务中读取的每个文档也必须写入。]”

下面的代码使用了async/await,运行良好

try{
   await db.runTransaction(async transaction => {
       const doc = await transaction.get(ref);
       if(!doc.exists){
            throw "Document does not exist";
       }
       const newCount = doc.data().count + 1;
       transaction.update(ref, {
           count: newCount,
       });
  })
} catch(e){
   console.log('transaction failed', e);
}

就我而言,运行交易的唯一方法是:

const firestore = admin.firestore();
const txRes = await firestore.runTransaction(async (tx) => {
    const docRef = await tx.get( firestore.collection('posts').doc( context.params.postId ) );
    if(!docRef.exists) {
        throw new Error('Error - onWrite: docRef does not exist');
    }
    const totalComments = docRef.data().comments + 1;
    return tx.update(docRef.ref, { comments: totalComments }, {});
});
我需要将我的“collection().doc()”直接添加到tx.get,并且在调用tx.update时,我需要应用“docRef.ref”,而没有“.ref”是不起作用的…

如果您查看,您会看到传递给
runTransaction
的函数是一个返回承诺的函数(transaction.get().then())。由于异步函数只是一个返回承诺的函数,您不妨编写
db.runTransaction(异步事务=>{})

如果要将数据从事务中传递出去,只需要从该函数返回一些内容。例如,如果只执行更新,则不会返回任何内容。还要注意,update函数返回事务本身,以便您可以链接它们:

try {
    await db.runTransaction(async transaction => {
      transaction
        .update(
          db.collection("col1").doc(id1),
          dataFor1
        )
        .update(
          db.collection("col2").doc(id2),
          dataFor2
        );
    });
  } catch (err) {
    throw new Error(`Failed transaction: ${err.message}`);
  }

updateFunction
不在您发布的代码中…请查看文档,
runTransaction
必须将
updateFunction
函数作为参数()接收到rendom Oops,我忘了。只需使用
doc.ref
而不是在事务中写入多个引用怎么办<代码>事务.更新(sfDocRef1,数据);事务。更新(sfDocRef2,数据)这与事务无关。您需要在更新时使用
t
。见阿尔斯基的回答@rendom请重新考虑您接受的答案,因为此答案没有正确使用事务(正如kuboon所指出的)。正如kuboon和ThijsKoerselman所指出的,此解决方案似乎没有正确使用事务。它使用事务获取文档,但更新在事务之外运行。答案需要更正,或者stackoverflow.com/a/52452831/683157应该是可接受的答案。如果读取失败,此解决方案是否仍然有效?async/await通常不应该在try/catch块中吗?提前感谢您的帮助:)如果由于并发编辑导致读取失败,它将自动重试事务。但是如果由于错误的事务导致读取失败,那么是的,您可能希望捕获事务失败。见:
try {
    await db.runTransaction(async transaction => {
      transaction
        .update(
          db.collection("col1").doc(id1),
          dataFor1
        )
        .update(
          db.collection("col2").doc(id2),
          dataFor2
        );
    });
  } catch (err) {
    throw new Error(`Failed transaction: ${err.message}`);
  }