Mr. Baks
Mr. Baks

Reputation: 317

How to trigger firebase http function in node.js?

I am trying to trigger an another function in Firebase Cloud function with javascript. But i always getting an error of Can't set headers after they are sent. Please take a look at my code below: ................. ................. ............ ................ ................. ............... ....................... .................. ..............

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);
    });
});

Upvotes: 0

Views: 149

Answers (2)

Juhil Somaiya
Juhil Somaiya

Reputation: 943

This is because you've sent multiple responses while the rule is that you only allowed sending one response. Please try to look at your code and optimize it in such a way that it contains only one response.

I can see you have multiple responses as below:

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

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

Upvotes: 1

Ivan Cherviakov
Ivan Cherviakov

Reputation: 538

I believe that you can have res.redirect and then res.status.send called one after another. When you writing endpoints there rule of a thumb: always send response and only do that once. Refactor your code so there no way you can make those two calls, but only one of them.

Upvotes: 0

Related Questions