首页 > 解决方案 > Firebase 实时数据库触发器:什么时候异步,什么时候不异步

问题描述

在有关 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因为未解决的承诺而出错。

标签: node.jsfirebasefirebase-realtime-databasegoogle-cloud-functions

解决方案


推荐阅读