首页 > 解决方案 > 访问节点上的所有子节点并为 Firebase 功能更新它们

问题描述

我在我的实时数据库的一个节点上检测到一些递归,我想删除(或设置 tu null)该特定节点。到目前为止,这是我的 firebase 功能:

exports.cleanForms = functions.https.onRequest((req, res) => {
    const parentRef = admin.database().ref("forms");
    return parentRef.once('value').then(snapshot => {
        snapshot.forEach(function(child) {
            admin.database().ref('forms/'+child.key+'/user/forms').set(null);
        });
    });
});

基本上它应该迭代表单节点内的所有记录并删除其用户/表单属性。

但是通过转到以下网址调用该函数: https://.cloudfunctions.net/cleanForms 给了我这个错误:

错误:无法处理请求

这就是我在日志上看到的:

10:47:57.818 PM cleanForms 函数执行耗时 13602 毫秒,完成状态:“连接错误”

表单节点的记录少于 3,000 条,但正如我之前提到的,它有一些递归。我不知道它是否由于它的大小或与之相关的原因而失败。

标签: firebasefirebase-realtime-databasegoogle-cloud-functions

解决方案


您正在使用 HTTPS 云功能:因此您必须“在最后向客户端发送响应”(观看 Doug Stevenson 的官方视频了解更多详情:https ://youtu.be/7IkUgCLr5oA )。

在您的情况下,函数的“结束”将是您的所有 set() 异步操作都将“完成”。由于该set()方法返回一个 Promise,因此您必须使用Promise.all()(再次观看此官方视频:https ://youtu.be/d9GrysWH1Lc )。

所以以下应该可以工作(但是未经测试):

exports.cleanForms = functions.https.onRequest((req, res) => {
    const parentRef = admin.database().ref("forms");
    parentRef.once('value')
    .then(snapshot => {
        const promises = [];
        snapshot.forEach(child => {
           promises.push(admin.database().ref('forms/'+child.key+'/user/forms').set(null));
        });
        return Promise.all(promises)   
    .then(results => {
        response.send({result: results.length + ' node(s) deleted'});
    })
    .catch(error => {
        response.status(500).send(error);
    });
});

推荐阅读