Firestore onSnapshot 承诺未解决

时间:2021-01-30 13:03:29

标签: javascript firebase google-cloud-firestore google-cloud-functions

我与 firebase 函数斗争了几天,今天我开始学习本教程 https://codelabs.developers.google.com/firebase-emulator。但是在第 16 步有这样的事情:

await new Promise((resolve) => {
  const unsubscribe = aliceCartRef.onSnapshot(snap => {
    const expectedCount = 2;
    const expectedTotal = 9.98;
    
    console.log(snap.data());
    if (snap.data().itemCount === expectedCount && snap.data().totalPrice == expectedTotal) {
      console.log("We're in if!");
      unsubscribe();
      console.log("After subscribe!");
      resolve();
      console.log("After resolve!");
    };
  });
});

我自己放置了console.log,发现onSnap 函数运行了两次。第一次 snap 对象看起来像这样:{ totalPrice: 0, itemCount: 0, ownerUID: 'alice' } 并且它不通过 if 条件。第二次 snap 是 { ownerUID: 'alice', totalPrice: 9.98, itemCount: 2 } 所以它通过 if 条件但 resolve() 不关闭 Promise。最后每次测试都因为超时而失败。

为什么 resolve() 在第二次调用中不起作用?

3 个答案:

答案 0 :(得分:0)

resolve() 只调用一次。您可以使用第二个调用。我认为您应该在 resolve() 之前获取所有数据。 例如:

db.collection("cities").where("state", "==", "CA")
    .onSnapshot(function(querySnapshot) {
        var cities = [];
        querySnapshot.forEach(function(doc) {
            cities.push(doc.data().name);
        });
        console.log("Current cities in CA: ", cities.join(", "));
    });

答案 1 :(得分:0)

像这样比较非整数总是很危险的:

snap.data().totalPrice == expectedTotal /* 9.98 */

JavaScript(和大多数环境)将此类非整数存储为所谓的浮点数,并且这些非整数的精度不可靠,因此很难与 == 进行比较。

我不确定这是否是您的问题的原因,但您可以使用范围比较快速测试是否是这样:

snap.data().totalPrice > 9.97 && snap.data().totalPrice < 9.99

如果这确实证明可以解决问题,请考虑以较小单位的整体增量存储金额。例如不是存储 9 美元和 98 美分,而是存储为 998 美元美分,这样比较就变成了:

snap.data().totalPrice === 998

整数的存储方式不同,并且没有浮点数所具有的精度问题。

答案 2 :(得分:0)

感谢回复。然而问题出在另一个地方。包装代码的 lambda 函数有参数“done”,这是没有完成函数的原因。这就是为什么测试没有通过。我的错。但是 codelabs that google is sharing 有一些损坏的代码 :(