Javascript Firestore:如何使用事务读取并写入我不知道的文档';你没有提到过吗?

Javascript Firestore:如何使用事务读取并写入我不知道的文档';你没有提到过吗?,javascript,node.js,firebase,google-cloud-firestore,Javascript,Node.js,Firebase,Google Cloud Firestore,我有一个文档,通过如下查询获取: var myPromise = db.collection("games").where("started", "==", false).orderBy("created").limit(1).get() 我需要创建一个事务,其中a从该文档中读取,然后写入。 例如(摘自文件): 我想用myPromise变量替换sfDocRef变量,但我不能,因为一个是文档引用,另一个是promis

我有一个文档,通过如下查询获取:

var myPromise = db.collection("games").where("started", "==", false).orderBy("created").limit(1).get()
我需要创建一个事务,其中a从该文档中读取,然后写入。 例如(摘自文件):

我想用myPromise变量替换sfDocRef变量,但我不能,因为一个是文档引用,另一个是promise。
如何在myPromise所代表的文档上创建事务?

一旦您实际执行该查询,就可以很容易地获得引用。你可以简单地:

  • 按现在的方式执行查询
  • 在查询结果中查找(处理查询结果时通常会这样做)
  • 使用DocumentSnapshot的
    ref
    属性获取文档的引用,它是
  • 在事务中使用该引用

  • 一旦您实际执行了该查询,引用就很容易获得。你可以简单地:

  • 按现在的方式执行查询
  • 在查询结果中查找(处理查询结果时通常会这样做)
  • 使用DocumentSnapshot的
    ref
    属性获取文档的引用,它是
  • 在事务中使用该引用

  • 您需要等待承诺得到解决,例如通过附加
    然后
    回调:

    myPromise.then((querySnapshot) => {
      let ref = querySnapshot.documents[0].ref;
      return db.runTransaction(function(transaction) {
        return transaction.get(ref).then(function(sfDoc) {
            if (!sfDoc.exists) {
                throw "Document does not exist!";
            }
            var newPopulation = sfDoc.data().population + 1;
            transaction.update(sfDocRef, { population: newPopulation });
        });
      }).then(function() {
        console.log("Transaction successfully committed!");
      }).catch(function(error) {
        console.log("Transaction failed: ", error);
      });
    });
    
    querySnapshot.documents[0].ref
    假设只有一个匹配文档,或者您只关心第一个文档。如果您关心的可能更多,则需要在查询快照中循环查看文档


    如果(且仅当)您希望事务确保在查询期间和在事务中写入此文档时未修改此文档,则仍需要
    获取事务中的特定文档。如果不需要,您可以使用
    QuerySnapshot
    中的
    QueryDocumentSnapshot
    ,您需要等待承诺解决,例如通过附加
    然后
    回调:

    myPromise.then((querySnapshot) => {
      let ref = querySnapshot.documents[0].ref;
      return db.runTransaction(function(transaction) {
        return transaction.get(ref).then(function(sfDoc) {
            if (!sfDoc.exists) {
                throw "Document does not exist!";
            }
            var newPopulation = sfDoc.data().population + 1;
            transaction.update(sfDocRef, { population: newPopulation });
        });
      }).then(function() {
        console.log("Transaction successfully committed!");
      }).catch(function(error) {
        console.log("Transaction failed: ", error);
      });
    });
    
    querySnapshot.documents[0].ref
    假设只有一个匹配文档,或者您只关心第一个文档。如果您关心的可能更多,则需要在查询快照中循环查看文档


    如果(且仅当)您希望事务确保在查询期间和在事务中写入此文档时未修改此文档,则仍需要
    获取事务中的特定文档。如果不需要,您可以使用
    QuerySnapshot

    中的
    QueryDocumentSnapshot
    来查看同一个文档,好像我正在阅读两次。一次是在等待评估承诺时,另一次是在我“获取”交易中的特定文档时。有没有一种方法可以让我只使用一个网络请求而不是两个?没有。查询是获取引用所必需的,但不能成为事务的一部分,因此在本例中需要两次读取。这就是为什么强烈建议您在代码中跟踪文档ID的原因之一。似乎我正在阅读同一文档两次。一次是在等待评估承诺时,另一次是在我“获取”交易中的特定文档时。有没有一种方法可以让我只使用一个网络请求而不是两个?没有。查询是获取引用所必需的,但不能成为事务的一部分,因此在本例中需要两次读取。这就是为什么强烈建议您在代码中跟踪文档ID的原因之一。似乎我正在阅读同一文档两次。一次是在等待评估承诺时,另一次是在我“获取”交易中的特定文档时。有没有一种方法可以只使用一个网络请求而不是两个?transaction.get()的文档中说,您可以向它传递引用或查询。尝试将查询传递给它。老实说,我不知道它是否会更快,实际上可能会更慢,因为您必须为事务锁定文档,这意味着它可以执行多次。似乎我在两次阅读同一份文件。一次是在等待评估承诺时,另一次是在我“获取”交易中的特定文档时。有没有一种方法可以只使用一个网络请求而不是两个?transaction.get()的文档中说,您可以向它传递引用或查询。尝试将查询传递给它。老实说,我不知道它是否会更快,实际上可能会更慢,因为您必须为事务锁定文档,这意味着它可以执行多次。