Обещание Firestore onSnapshot не разрешается

#javascript #firebase #google-cloud-firestore #google-cloud-functions

#javascript #firebase #google-облако-firestore #google-cloud-функции

Вопрос:

Я борюсь с функциями 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 amp;amp; snap.data().totalPrice == expectedTotal) {
      console.log("We're in if!");
      unsubscribe();
      console.log("After subscribe!");
      resolve();
      console.log("After resolve!");
    };
  });
});
 

Я поставил консоль.я сам зарегистрировался и обнаружил, что функция onSnap выполняется дважды. В первый раз объект привязки выглядит следующим образом: { TotalPrice: 0, ItemCount: 0, ownerUID: ‘alice’ } и не проходит условие if. Во второй раз привязка { ownerUID: ‘alice’, TotalPrice: 9.98, ItemCount: 2}, поэтому она проходит, если условие, но resolve() не закрывает обещание. Наконец, тест завершается неудачей каждый раз из-за тайм-аута.

Почему resolve() не работает во втором вызове?

Ответ №1:

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(", "));
    });
 

Ответ №2:

Сравнение нецелых чисел, подобных этому, всегда опасно:

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

JavaScript (и большинство сред) хранят такие нецелые числа как так называемые числа с плавающей запятой, и они имеют ненадежную точность, что делает их очень трудными для сравнения == .

Я не уверен, является ли это причиной вашей проблемы, но вы можете быстро проверить, так ли это, используя сравнение диапазона:

 snap.data().totalPrice > 9.97 amp;amp; snap.data().totalPrice < 9.99
 

Если это действительно решит проблему, рассмотрите возможность сохранения сумм в целых приращениях меньшей единицы. Например, вместо хранения 9 долларов и 98 центов сохраните его как 998 долларовых центов, чтобы сравнение стало:

 snap.data().totalPrice === 998
 

Целые числа хранятся по-разному и не имеют такой проблемы с точностью, как числа с плавающей запятой.

Ответ №3:

спасибо за ответы. Однако проблема крылась в другом месте. Лямбда-функция, которая обертывает код, имела параметр «done», который был причиной того, что функция не была завершена. Вот почему тест не проходит. Моя ошибка. Но в codelabs, которыми делится Google, есть несколько неработающих кодов: (