Reputation: 2466
I'm trying to have a Google Cloud Function that invokes an external API. I'm on the Blaze plan, so I should be able to make external invocations. I have an Express app and these test routes:
app.get('/helloWorld', (request, response) => {
response.send('Hello there');
});
app.get('/test', (request, response) => {
request.get("https://postman-echo.com/get?foo1=bar1&foo2=bar2", (error, res, body) => {
console.log('error:', error);
console.log('statusCode:', res && res.statusCode);
console.log('body:', body);
if(error) {
response.status(400).send(error);
}
response.status(200).send(body);
});
});
The /helloWorld route works fine, but the /test route times out every time. If I look at the Firebase logs for the function I see:
9:19:29.837 PM
api
Function execution started
9:20:29.839 PM
api
Function execution took 60002 ms, finished with status: 'timeout'
9:21:09.263 PM
api
Function execution started
9:21:09.277 PM
api
Function execution took 14 ms, finished with status code: 200
9:21:13.515 PM
api
Function execution started
9:22:13.516 PM
api
Function execution took 60002 ms, finished with status: 'timeout'
So, it's like it just keeps calling the function over and over in an infinite loop and times out each time, and nothing gets returned to the client until it finally just times out. What am I doing wrong here?
Upvotes: 1
Views: 1102
Reputation: 600141
Since you're calling a 3rd party asynchronous API, you have to tell Cloud Functions when your code is done. You do this by returning a promise from the function, and then making sure that promise resolves when all (asynchronous) work is done.
app.get('/test', (request, response) => {
return new Promise((resolve, reject) {
request.get("https://postman-echo.com/get?foo1=bar1&foo2=bar2", (error, res, body) => {
console.log('error:', error);
console.log('statusCode:', res && res.statusCode);
console.log('body:', body);
if(error) {
response.status(400).send(error);
reject(error);
}
response.status(200).send(body);
resolve();
});
});
});
You might want to consider using a library like request-promise
to prevent the need for your own Promise
logic.
Upvotes: 2