Firestore:如何使用事务读取并写入我没有引用的文档?

时间:2020-08-01 20:57:26

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

我有一个文档,它通过这样的查询来获取:

var myPromise = db.collection("games").where("started", "==", false).orderBy("created").limit(1).get()

我需要创建一个事务,在该事务中读取此文档,然后再写入。 例如(摘自文档):

// Create a reference to the SF doc.
var sfDocRef = db.collection("cities").doc("SF");

// Uncomment to initialize the doc.
// sfDocRef.set({ population: 0 });

return db.runTransaction(function(transaction) {
    // This code may get re-run multiple times if there are conflicts.
    return transaction.get(sfDocRef).then(function(sfDoc) {
        if (!sfDoc.exists) {
            throw "Document does not exist!";
        }

        // Add one person to the city population.
        // Note: this could be done without a transaction
        //       by updating the population using FieldValue.increment()
        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);
});

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

2 个答案:

答案 0 :(得分:1)

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

  1. 立即执行查询
  2. 在查询结果中找到DocumentSnapshot(与处理查询结果时通常一样)
  3. 使用DocumentSnapshot的ref属性获取文档的引用,即DocumentReference
  4. 在交易中使用该引用。

答案 1 :(得分:1)

您需要等待承诺解决,例如,通过附加then回调:

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假定只有一个匹配的文档,或者您只关心第一个文档。如果您还有更多需要关注的地方,则需要遍历查询快照中的文档。

您仍然需要get事务内的特定文档如果(且仅在以下情况下)您希望事务确保该文档在查询和编写之间未被修改它在交易中。如果不需要,可以使用QueryDocumentSnapshot中的QuerySnapshot