0
votes

We have a React application using a Firebase backend. Several of our larger customers discovered that their network security blocks calls to certain URLs where the SSL certificate may be questionable. One URL that was commonly getting blocked was cloudfunctions.net which is used by Firebase Cloud Functions as the default cloud functions endpoint.

Rather than asking every potential customer to update their network security and whitelist cloudfunctions.net we instead need to have a more robust solution that will allow us to host cloud functions at our custom domain with a dedicated SSL certificate. The bulk of this solution should be handled by creating a GCP Static IP address, and using a GCP Load Balancer to reroute calls to this IP address through to our cloud functions.

There are many articles on SO about using Firebase Hosting to reroute calls to your custom domain through to your cloud functions, such as Use custom domain for firebase function http calls

What isn't as clearly documented is how to initialize the firebase-js SDK for your own React client to call a custom domain when using functions().httpsCallable as part of firebase.functions().

When making a request from our web app to cloud functions using httpsCallable:

const { data } = firebase.functions().httpsCallable('myFunction');

the default SDK behaviour makes a request to:

https://<region>-<firebase-project-id>.cloudfunctions.net/myFunction

The official docs make vague reference to initializing Firebase Functions with a region variable. They also share how to do this when initializing the client SDK here.

const functions = firebase().app().functions('region-string');

What I wanted to achieve was to change the default behaviour of the firebase-js SDK so that when making calls to cloud functions within my react client these requests would call my custom domain (I'm using a GCP load balancer to provide a custom domain endpoint for cloud functions).

1

1 Answers

2
votes

It turns out that you can provide firebase-js SDK functions with a config of either a region OR a custom domain. This is shown in the SDK code repository here.

So to ensure your client always makes httpsCallable transactions to your custom domain you can initialize Firebase Functions like so:

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FUNCTIONS PROJECT ID ###'
  databaseURL: 'https://### YOUR DATABASE NAME ###.firebaseio.com',
});

// Initialize Cloud Functions through Firebase
const functions = firebase.app().functions('https://customdomain.com/');

NOTE: This solution requires you to have also configured DNS configuration to redirect your custom domain to a GCP Load Balancer. When combining a load balancer with a urlMap you can have calls to https://customdomain.com/myFunction routed to your myFunction cloud function.

The full transaction would look like:

client SDK -> httpsCallable -> custom domain -> GCP static IP -> GCP Load Balancer -> GCP urlMap -> GCP cloud functions Backend Network Group -> cloud functions.

You can find instructions for configuring a GCP load balancer and Serverless NEG here: https://cloud.google.com/load-balancing/docs/https/setting-up-https-serverless#cloud-functions

I hope this saves someone else much searching. I was surprised I needed to read the firebase-sdk code to find this out.