【问题标题】:How to trigger firebase http function in node.js?如何在 node.js 中触发 firebase http 功能?
【发布时间】:2019-11-26 06:48:47
【问题描述】:

我正在尝试使用 javascript 在 Firebase Cloud 函数中触发另一个函数。但我总是收到Can't set headers after they are sent. 的错误,请看下面我的代码:.............. ………………………………………………………………………………………………………………………………………………………………………… …………………………………………………………………………………………………………………………………………………………………… .... ........

exports.productIndexShuffleOne = functions.https.onRequest(async (req, res) => {
    const interval = req.query.interval;
    console.log("interval: "+interval);

    const productRef = admin.firestore().collection("Products");
    const adminRef = admin.firestore().collection("Admin").doc("totalProd").get();
    const dateRef = admin.firestore().collection("Admin").doc("totalProd").collection("indexShuffle").doc("productShuffle").get();

    return dateRef.then(documentSnapshot => {
        const setDate = documentSnapshot.get('date').seconds;

        var nextDay = setDate;
        console.log("Date: "+nextDay);

        const x = setInterval(function() {
            clearInterval(x);
            return Promise.all([adminRef]).then(result => {
                const totalNum = result[0].data().totalNumber;

                console.log("totalNum: "+totalNum);

                var numberList = [];
                var index = 1;
                while(index <= totalNum){
                    numberList.push(index);
                    index++;
                }

                var cidx, ridx, tmp;
                cidx = numberList.length;
                while (cidx !== 0) {
                    ridx = Math.floor(Math.random() * cidx);
                    cidx--;
                    tmp = numberList[cidx];
                    numberList[cidx] = numberList[ridx];
                    numberList[ridx] = tmp;
                }
                console.log(numberList);

                var counter = 0;
                return productRef.get().then(snapshot => {
                    snapshot.forEach(doc => {
                    const prodID = doc.get('productID');
                    const index = doc.get('index');

                    var newIndex = numberList[counter];
                    counter++;
                    console.log("oldIndex: "+index);
                    console.log("newIndex: "+newIndex);

                    productRef.doc(prodID).update({
                        index: newIndex
                        }, {merge: true});
                    });

                    return res.redirect('https://us-central1-myfunction-123456.cloudfunctions.net/productIndexShuffleTwo?interval='+interval);
                })
                .catch(err => {
                    console.log('Error getting documents', err);
                });
            });
        }, interval);
        return res.status(203).send(interval);
    }).catch(function(err) {
        console.error(err);
    });
});

【问题讨论】:

  • 这看起来不像是部署到 Cloud Functions 的完整代码。另外,为什么要使用 setInterval?
  • 请稍等,我将包含完整的功能。我想在部署另一个函数的触发器之前等待 20 分钟,这就是我包含间隔的原因。

标签: javascript node.js google-cloud-platform google-cloud-functions


【解决方案1】:

这是因为您发送了多个响应,而规则是您只允许发送一个响应。请尝试查看您的代码并对其进行优化,使其仅包含一个响应。

我可以看到你有多个回复如下:

1 -> return res.redirect('https://us-central1-myfunction-123456.cloudfunctions.net/productIndexShuffleTwo?interval='+interval);

2 -> return res.status(203).send(interval);

【讨论】:

    【解决方案2】:

    我相信你可以一个接一个地调用 res.redirect 和 res.status.send 。当您编写端点时,有一个经验法则:始终发送响应并且只执行一次。重构您的代码,这样您就无法进行这两个调用,而只能调用其中一个。

    【讨论】:

    • 如果我使用 res.redirect 会调用另一个函数吗?
    • 您可以进行 res.redirect,然后对任何函数进行任何其他次数的调用。这里的重要部分是不调用 res.redirect 或 res.send 或任何其他方法,再次发送响应,因为在您第一次发送响应后,您无法再次发送它 - 它已经消失了。因此你当然不能修改它。
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2020-10-20
    相关资源
    最近更新 更多