HTTP函数返回初始数组值

时间:2018-02-16 08:19:55

标签: javascript firebase firebase-realtime-database google-cloud-functions

我已经获得了这个firebase云功能,我已经编码来计算注册用户数量与任意用户的数量。

// Recalc totals user 
exports.recalcTotalUsers = functions.https.onRequest((req, res) => {
    var arr = {
        anonymous: 0,
        registered: 0
    };

    console.log('starting recalcTotalUsers');
    admin.database().ref("users").once("value").then((snapshot) => {
        snapshot.forEach(function (uid) {
            if (uid.child('/email').val() == ANONYMOUS_STRING) {
                arr.anonymous++;
            } else {
                arr.registered++;
            }
            console.log(`1. ${arr.anonymous}:${arr.registered}`)
        })
    });
    res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)  
 });

当函数返回时,如果它们具有不同的值,我总是得到anonymous = 0和registered = 0事件......我做错了什么?

2 个答案:

答案 0 :(得分:3)

数据库查询是异步的,不会立即完成。您需要使用admin.database().ref("users").once()的promise返回来等待查询结果,并且只有在成功后才将响应发送给客户端。目前,您的响应会在查询完成之前发送给客户端。

相反,将响应放在回调中,来自once()的回复,而不是在外面:

admin.database().ref("users").once("value").then((snapshot) => {
    snapshot.forEach(function (uid) {
        if (uid.child('/email').val() == ANONYMOUS_STRING) {
            arr.anonymous++;
        } else {
            arr.registered++;
        }
        console.log(`1. ${arr.anonymous}:${arr.registered}`)
    })
    res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)  
});

Please read more about Firebase asynchronous APIs.

答案 1 :(得分:3)

你必须提出你的回复!因为现在,让我们来看看你的代码:

admin.database().ref("users").once("value").then((snapshot) => {
    snapshot.forEach(function (uid) {
        if (uid.child('/email').val() == ANONYMOUS_STRING) {
            arr.anonymous++;
        } else {
            arr.registered++;
        }
        console.log(`1. ${arr.anonymous}:${arr.registered}`)
    })
});
res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)

您可能知道,数据库函数都是asynchronous,这意味着它们

  • 需要时间执行
  • 有承诺,因此在下一行代码执行之前不要等待

    res.status(200)。发送(ok registered: ${arr.registered}, anonymous: ${arr.anonymous}

在查询"users"快照之前执行该行。 你必须移动它,最佳实践将是另一个承诺(.then(...)),但你可以这样做:

admin.database().ref("users").once("value").then((snapshot) => {
    snapshot.forEach(function (uid) {
        if (uid.child('/email').val() == ANONYMOUS_STRING) {
            arr.anonymous++;
        } else {
            arr.registered++;
        }
        console.log(`1. ${arr.anonymous}:${arr.registered}`)
    })
    res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)
});