Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Cloud Function from another Cloud Function

I am using a Cloud Function to call another Cloud Function on the free spark tier.

Is there a special way to call another Cloud Function? Or do you just use a standard http request?

I have tried calling the other function directly like so:

exports.purchaseTicket = functions.https.onRequest((req, res) => {       fetch('https://us-central1-functions-****.cloudfunctions.net/validate')     .then(response => response.json())     .then(json => res.status(201).json(json)) }) 

But I get the error

FetchError: request to https://us-central1-functions-****.cloudfunctions.net/validate failed, reason: getaddrinfo ENOTFOUND us-central1-functions-*****.cloudfunctions.net us-central1-functions-*****.cloudfunctions.net:443

Which sounds like firebase is blocking the connection, despite it being a google owned, and therefore it shouldn't be locked

the Spark plan only allows outbound network requests to Google owned services.

How can I make use a Cloud Function to call another Cloud Function?

like image 851
ro-savage Avatar asked Mar 14 '17 10:03

ro-savage


People also ask

How do I call a service function from a cloud?

In the New principals field, enter the identity of the calling function. This should be a service account email. Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu. Click Save.


2 Answers

You don't need to go through the trouble of invoking some shared functionality via a whole new HTTPS call. You can simply abstract away the common bits of code into a regular javascript function that gets called by either one. For example, you could modify the template helloWorld function like this:

var functions = require('firebase-functions');  exports.helloWorld = functions.https.onRequest((request, response) => {   common(response) })  exports.helloWorld2 = functions.https.onRequest((request, response) => {   common(response) })  function common(response) {   response.send("Hello from a regular old function!"); } 

These two functions will do exactly the same thing, but with different endpoints.

like image 71
Doug Stevenson Avatar answered Sep 20 '22 14:09

Doug Stevenson


To answer the question, you can do an https request to call another cloud function:

export const callCloudFunction = async (functionName: string, data: {} = {}) => {     let url = `https://us-central1-${config.firebase.projectId}.cloudfunctions.net/${functionName}`     await fetch(url, {         method: 'POST',         headers: {             'Content-Type': 'application/json',         },         body: JSON.stringify({ data }),     }) } 

(Note we are using the npm package 'node-fetch' as our fetch implementation.)

And then simply call it:

callCloudFunction('search', { query: 'yo' }) 

There are legitimate reasons to do this. We used this to ping our search cloud function every minute and keep it running. This greatly lowers response latency for a few dollars a year.

like image 34
jahooma Avatar answered Sep 18 '22 14:09

jahooma