简体   繁体   中英

firebase cloud functions doesn't execute the whole function?

I have a firebase cloud function that runs and checks the objects in the firestore database and does some operations. But it doesn't run whole function and randomly stops in the middle of the function. I first thought it timeouts but timeout value is 60 sec, my function runs in 2-3 sec. But most of the operations require promises since they are doing asynchronous operations like database operations. So to make sure function doesn't stop before executing all of it I push them into a promises array and the return the Promise.all(promises). Here are how my function looks like

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   admin.firestore().collection('someCollection').get().then(res => {
        res.forEach(item => {
            let data = item.data();

            promises.push(somePromise);
            console.log('some Promise is pushed')
            promises.push(anotherPromise)
            .....
        })
   })

   return Promise.all(promises);
})

So in the above code some promises get executed some are not. Not sure what is the reason. None of the promises throws error. But the reason probably is they are not even getting pushed to array as I don't see that console.log run in the logs section sometimes. Sometimes it runs sometimes it doesn't. Couldn't figure out why it stops somewhere in the middle.

I started the question my design anymore. Maybe I should have another function for each of the promises that I should execute. Or I have a functions that runs on update of an object for example. And it should do bunch of things. I mean is bunch of read and write. Bunch of promises. So is it better to have another onUpdate function for each operation or put it all of it into one onUpdate function? Need help on this. Thanks in advance.

It's easy to see what's going on, if you add some logging to your code:

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   console.log('Before starting to read data...');
   admin.firestore().collection('someCollection').get().then(res => {
       console.log('Got data...');
   })
   console.log('After starting to read data...');

   return Promise.all(promises);
})

When you run the code like this, it logs:

Before starting to read data...

After starting to read data...

Got data...

So when you return Promise.all(...) , you haven't gotten the data from Firestore yet, and there are no promises to wait for. So Cloud Functions may end the container that runs your code at any time.

So the solution is to make sure all promises are gathered, before you return them. You do this by putting the Promise.all(...) inside the callback, and then using another return to bubble the promise up so that it gets returned to Cloud Functions.

export const func = functions.pubsub.schedule('every 10 minutes').onRun(context => {
   const promises = any[] = [];
   //here I pass the array to some other function to gather the promises that are 
   //made there
   doSomeJob(promises)

   return admin.firestore().collection('someCollection').get().then(res => {
        res.forEach(item => {
            let data = item.data();

            promises.push(somePromise);
            console.log('some Promise is pushed')
            promises.push(anotherPromise)
            .....
        })
        return Promise.all(promises);
   })

})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM