Multitut
Multitut

Reputation: 2169

Access all children on node and update them for Firebase Function

I detected some recursion on one of the nodes of my realtime database and I want to delete (or set tu null) that specific node. This is my firebase function so far:

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

Basically it should iterate all the records inside the forms node and delete its user/forms property.

But calling that function by going to this url: https://.cloudfunctions.net/cleanForms gives me this error:

Error: could not handle the request

And this is what I see on the logs:

10:47:57.818 PM cleanForms Function execution took 13602 ms, finished with status: 'connection error'

The forms node has less than 3,000 records but as I mentioned before, it has some recursion on it. I don't know if it is failing due to its size or something related to that.

Upvotes: 0

Views: 313

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83058

You are using an HTTPs Cloud Function: therefore you must "send a response to the client at the end" (Watch this official video by Doug Stevenson for more detail: https://youtu.be/7IkUgCLr5oA).

In your case, the "end" of the function will be when ALL of your set() asynchronous operations will be "done". Since the set() method returns a Promise, you have to use Promise.all() (again, watch this official video: https://youtu.be/d9GrysWH1Lc ).

So the following should work (not tested however):

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

Upvotes: 1

Related Questions