【问题标题】:Firebase last 10 data retrieving from database in Cloud FunctionFirebase 从 Cloud Function 中的数据库检索的最后 10 个数据
【发布时间】:2017-11-16 14:28:59
【问题描述】:

下面的云函数只返回第一个数据而不是10个:

exports.viewdata = functions.https.onRequest((req, res) => {
    const userId = req.query.user;
    return admin.database().ref('users/' + userId)
    .orderByKey()
    .limitToLast(10)    
    .on('child_added', function(snapshot) {
        snapshot.forEach(function(data) {
        res.status(200).send(data.val());
        });
     });
});

请帮我解决这个问题。

【问题讨论】:

    标签: node.js firebase firebase-realtime-database google-cloud-functions


    【解决方案1】:

    使用send()end()redirect()terminate a HTTP Cloud Function

    始终以 send()redirect()end() 结束 HTTP 函数。否则,您的函数可能会继续运行并被系统强制终止。

    在您的示例中,您在每个子快照的 forEach 迭代中调用 res.status(200).send(data.val());,因此它只会有机会发送一个响应。

    同样,因为你使用了child_added event listener,它会为指定路径上的每个孩子触发一次。

    如果您需要一次响应所有查询数据,最好使用value event listener,它会在一个响应中从您的查询中检索所有数据:

    exports.viewdata = functions.https.onRequest((req, res) => {
        const userId = req.query.user;
        admin.database().ref('users/' + userId)
        .orderByKey()
        .limitToLast(10)    
        .on('value', function(snapshot) {
            res.status(200).send(snapshot.val());
        });
    });
    

    但是,如果您打算分别为每个孩子构建响应,您可以使用 res.write() 将数据写入响应,然后最终使用 end() 发送:

    exports.viewdata = functions.https.onRequest((req, res) => {
        const userId = req.query.user;
        admin.database().ref('users/' + userId)
        .orderByKey()
        .limitToLast(10)    
        .on('value', function(snapshot) {
            snapshot.forEach(function(data) {
                res.write(data.val());
            });
            res.status(200).end();
        });
    });
    

    或者,您可以将它们添加到列表中,然后再将它们作为响应全部发回。不过,您在这里采用的方法完全取决于您的最终目标。


    与您最初的问题无关,但为了完整起见,请参阅来自 cmets 的以下观察和旁注:

    • HTTPS 触发器不需要 admin.database().ref()return 语句,因为它们有 different lifecycle than other triggers 并且不需要返回承诺。

    • 如果您在检索到必要的数据后不需要侦听进一步的更改,您应该考虑使用once()(到read data once)而不是on() 或删除on() 侦听器off()

    【讨论】:

    • 差不多。完成这项工作还需要做一些事情:1) 侦听value 事件,以便回调一次获取所有 10 个孩子。 2) 使用forEach构建结果,使用snapshot.val()一次性发送10个结果。
    • @FrankvanPuffelen 啊,是的,我错过了child_added 部分!谢谢弗兰克,我会更新答案。
    • 这里不需要return,因为来自 HTTPS 函数的返回值没有任何意义(而且,on() 甚至不会返回承诺或任何类似的有用信息) .
    • 还可以考虑使用off() 删除监听器,这样它就不会在函数返回后继续监听——这可能是一种浪费。
    • @DougStevenson 谢谢你是对的,我今天早些时候answered another similar question 需要删除return。此外,在这里使用once() 会更好,以避免让监听器保持连接状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多