В документации по триггерам Firebase мы не видим слово async
: https://firebase.google.com/docs/functions/database-events#reading_the_previous_value Допустим, у меня есть две версии функции, одна с async
, а другая без, например:
exports.recountTotalCaloriesOnUpdate2 = functions.database.ref('/mealsOf/{userId}/{day}/meals')
.onUpdate(
(change,context) => {
let uid= context.params.userId;
let day= context.params.day;
if ( !change.after.exists() ) return null ;
if ( !change.before.exists() ) return null ;
const collectionRef = change.after.ref;
let finalSum = collectionRef.ref.once('value').then((snap) => {
let sum = 0;
snap.forEach((child) => {
//console.log(child.val().numCalories);
sum = sum + parseInt(child.val().numCalories);
});
return sum;
});
/*
return await counterRef.ref.transaction((cnt) => {
return finalSum;
});
*/
return dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(finalSum);
/*
return await dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(finalSum).then( (a) => {
return null ;
}).catch( (error) => {
return null ;
});
*/
}
);
и с async
:
exports.recountTotalCaloriesOnUpdate2 = functions.database.ref('/mealsOf/{userId}/{day}/meals')
.onUpdate(
async(change,context) => {
let uid= context.params.userId;
let day= context.params.day;
if ( !change.after.exists() ) return null ;
if ( !change.before.exists() ) return null ;
const collectionRef = change.after.ref;
let finalSum = await collectionRef.ref.once('value').then((snap) => {
let sum = 0;
snap.forEach((child) => {
//console.log(child.val().numCalories);
sum = sum + parseInt(child.val().numCalories);
});
return sum;
});
/*
return await counterRef.ref.transaction((cnt) => {
return finalSum;
});
*/
//return dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(finalSum);
return await dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(finalSum).then( (a) => {
return null ;
}).catch( (error) => {
return null ;
});
}
);
В чем разница?Это имеет значение для Firebase?Кроме того, при вычислении finalSum
, мой let finalSum = await ...
, я проверяю, доступен ли этот finalSum
в последующих строках, т. Е. Выполняет ли поток выполнения .join()
вычисление на языке Java?Но настоящая проблема с этим кодом состоит в том, что
return await dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(finalSum).then( (a) => {
return null ;
}).catch( (error) => {
return null ;
});
всегда дает мне сообщение: для случая без async
и для дела с async
.
У меня есть путь mealsOf/{userId}/{day}/meals/{mealId}
, и я проталкиваю туда новую еду.Поэтому я установил этот триггер для обновления счетчика на mealsOf/{userId}/{day}/totalCalories
всякий раз, когда происходит запись / обновление по пути mealsOf/{userId}/{day}/meals
.Как справиться с вышеуказанными исключениями?
РЕДАКТИРОВАТЬ: Вы можете прочитать о async/await
в другом месте, например, https://hackernoon.com/understanding-async-await-in-javascript-1d81bb079b2c (просто случайная ссылка, потеря материала там!) Что касается моего конкретного случаяЯ позволил async
быть там, обратил внимание на фактическое сообщение об ошибке и заменил последнюю строку на это:
return dbroot.ref(`mealsOf/${uid}/${day}/totalCalories`).set(""+finalSum, (error) => {
if ( error )
console.log(error.message);
});
и, наконец, получил мои тесты с чистым выполнением.Итак, NaN
говорит нам, что безопаснее всего конвертировать все в строку.
РЕДАКТИРОВАТЬ: Посмотрите Функции Firebase: Непонятная «ошибка соединения» , чтобы увидеть, что даже в последней вставленной мной строке должно быть ключевое слово await
.В противном случае иногда вы можете получить ошибку connection error
из-за неразрешенных обещаний.