59

I was wondering if its possible to use a firebase cloud function to send a post request to a non-google server (from what I can find I need to be on the blaze plan in order to interact with non google servers)

Basically I want to POST to an external server running on an arduino whenever a value is added to my database.

I have looked through the docs and found examples of having a cloud function respond to an HTTP post request (HTTP cloud functions) but can't seem to find any examples of posting to an external server. Is this possible?

gligoran
  • 3,267
  • 3
  • 32
  • 47
Stone Preston
  • 1,828
  • 4
  • 20
  • 35

5 Answers5

65

Note: request package has been deprecated as stated in the npm page request-npm. Consider using other alternatives like axios

This can be done using the request module:

// import the module
var request = require('request');

// make the request
request('put your external url here', function (error, response, body) {
    if (!error && response.statusCode == 200) {
        //here put what you want to do with the request
    }
})

NOTE: This will only work on paid plans. It is not possible to call non-google APIs using the free Spark plan as explained on the Firebase pricing page:

The Spark plan allows outbound network requests only to Google-owned services. Inbound invocation requests are allowed within the quota. On the Blaze plan, Cloud Functions provides a perpetual free tier. The first 2,000,000 invocations, 400,000 GB-sec, 200,000 CPU-sec, and 5 GB of Internet egress traffic is provided for free each month. You are only charged on usage past this free allotment. Pricing is based on total number of invocations, and compute time. Compute time is variable based on the amount of memory and CPU provisioned for a function. Usage limits are also enforced through daily and 100s quotas. For more information, see Cloud Functions Pricing.

stodi
  • 1,549
  • 13
  • 23
  • 4
    Also requires paid firebase account - Works on Blaze plan – Arkelyan May 11 '17 at 17:31
  • 6
    This will work on unpaid accounts (Spark Plan) if your requests are to another Google owned service. "The Spark plan allows outbound network requests only to Google-owned services. Inbound invocation requests are allowed within the quota." (https://firebase.google.com/pricing/) – Devin Carpenter May 24 '17 at 00:07
  • 3
    I get `Error: Error parsing triggers: Cannot find module 'request'` when doing a firebase deploy with `var request = require('request');` – matth Jul 17 '17 at 20:36
  • 2
    @matth you need to install the request module `npm install request` – stodi Jul 26 '17 at 14:56
  • 1
    Yes, it does @ImMathan – stodi Oct 13 '17 at 21:27
  • 7
    it's more like `npm i --save request` from within the ./project/functions folder – Cerberus Dec 15 '17 at 09:35
  • 1
    @Cerberus answer should be added to the above answer to make it complete! – UKDataGeek Dec 25 '17 at 23:00
  • The Spark plan allows outbound network requests ONLY to Google-owned services. – Basit Jan 25 '18 at 08:18
  • To clarify what a Google-owned service is and is not; It is not products that google owns like YouTube and so on. It is only the services on this list. https://cloud.google.com/functions/docs/concepts/services – myself Apr 02 '18 at 16:02
  • Does anyone know whether this restriction applies when testing cloud functions locally? – postmechanical May 22 '19 at 14:25
  • @postmechanical - External API's seem to work locally for me on the free plan – Kyle Delaney Sep 04 '19 at 02:04
  • The output window says `Unknown network resource requested`. Is there somewhere we're supposed to configure network resources? – Kyle Delaney Sep 04 '19 at 02:36
  • Even Google reCAPTCHA v3 is not allowed in the Google Cloud Functions despite still **google.com**. [See my post here](https://stackoverflow.com/questions/61651415/verifying-recaptcha-v3-in-firebase-function-causes-cors-issue). – Antonio Ooi May 17 '20 at 00:39
  • @gligoran I'm getting an error and supposing it's related to a missing certificate. _"Error: write EPROTO 68444601759552:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure"_ Is anyone has an idea to solve? Should I need to setup a certificate, if so, then how? * I'm on blaze plan Thanks in advance – hasany May 17 '20 at 21:14
  • 2
    anyone stumbling upon this - Request is unfortunately deprecated : https://www.npmjs.com/package/request – user1012500 Dec 21 '20 at 15:59
  • 1
    @user1012500 as the message says: request is unfortunately deprecated. Consider using an alternative. – stodi Dec 22 '20 at 15:14
  • 1
    Yup that's why I had posted, might be good to edit this to identify that the request is package has been deprecated just to help someone who comes across this without checking the package details. – user1012500 Jan 10 '21 at 15:41
  • Does this mean that in Blaze plan, as long as you don't hit the quota you are free of charge and that free tier is refreshing every month? – Bitwise DEVS Nov 26 '21 at 05:09
8

You need to install the package. Go to Firebase-Funcions directory in Terminal and type

npm install request

OR

npm install request-promise

Use this example for test: https://www.npmjs.com/package/request

madsroskar
  • 1,138
  • 13
  • 26
RodolfoNeto
  • 483
  • 5
  • 4
  • 2
    Actually, for successful use with firebase functions all `npm install`s need to be done with `--save` flag. Just something to keep in mind to avoid the annoying "cannot find module" errors while deploying. – HirdayGupta Aug 13 '18 at 20:20
  • 2
    @HirdayGupta since [npm@5.0.0 (may 25, 2017)](https://blog.npmjs.org/post/161081169345/v500), `--save` is added by default – Nino Filiu Feb 19 '19 at 22:35
3

Remember to install the module within the functions folder!

cd functions
npm i --save request
Cesare
  • 9,139
  • 16
  • 78
  • 130
2

For those of you who want to post with a JSON body this is how you can do it. (I know I needed this a while ago)

export function postWithBodyToExternalUrl(url: string, bdy: any): Promise<ReqResponse> {

  const request = require('request');

  const options = {
    url: url,
    json: true
  };
  return new Promise(function (resolve, reject) {
    request(options, function (err, resp) {
      if (err) {
        console.log(err);
        reject({ err: err });
      }
      resolve(bdy);
    });
  });
}
Ruan
  • 3,969
  • 10
  • 60
  • 87
1

axios is also one of the great library to handle network calls. Some features:

  • Make XMLHttpRequests from the browser
  • Make http requests from node.js
  • Supports the Promise API
  • Intercept request and response
  • Transform request and response data
  • Cancel requests
  • Automatic transforms for JSON data
  • Client side support for protecting against XSRF
  • 67k+ stars on github
  • github documentation for more
Hemant Kaushik
  • 1,706
  • 15
  • 22