The user types a message into a chat client (a website). This message is sent through to a cloud function set up on firebase. The cloud function then queries a 3rd party API which returns a response. This response needs to be sent back to the client to be displayed.
So basically my client calls a cloud function like so...
var submitMessage = firebase.functions().httpsCallable('submitMessage');
submitMessage({message: userMessage}).thenfunction(result) {
//Process result
});
My cloud function looks like this...
exports.submitMessage = functions.https.onCall((data, context) => {
request({
url: URL,
method: "POST",
json: true,
body: queryJSON //A json variable I've built previously
}, function (error, response, body) {
//Processes the result (which is in the body of the return)
});
return {response: "Test return"};
});
I have included the request package and the API call itself works perfectly. I can print the result to the console from within the return function of the request. However, obviously because the request is asynchronous I can't just create a global variable and assign the result body to it. I have seen that you can call a callback function once the request is finished. However, I need to somehow pass that through to the cloud function return value. So put simply, I need to do this...
exports.submitMessage = functions.https.onCall((data, context) => {
var gBody;
request({
url: URL,
method: "POST",
json: true,
body: queryJSON //A json variable I've built previously
}, function (error, response, body) {
gBody = body;
});
return gBody;
});
(Yes, I am aware of this post... How do I return the response from an asynchronous call? but yeah as I said I need the variable scope to be within the cloud function itself so that I am able to return the value back to the client. Either I don't understand the methods used in that post or it does not accomplish what I am asking)
The approach in your last snippet can't work: by the time your return gBody
runs the callback from the 3rd party API hasn't been called yet, so gBody
is empty.
As the Cloud Functions documentation says:
To return data after an asynchronous operation, return a promise. The data returned by the promise is sent back to the client.
So you just return a promise, and then later resolve that promise with the data from the 3rd party API.
exports.submitMessage = functions.https.onCall((data, context) => {
return new Promise(function(resolve, reject) {
request({
url: URL,
method: "POST",
json: true,
body: queryJSON //A json variable I've built previously
}, function (error, response, body) {
if (error) {
reject(error);
}
else {
resolve(body)
}
});
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With