Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deploying Firebase App with Service Account to Heroku (environment variables with dotenv)

I have a node application that uses a firebase service account. I would like to deploy the app to Heroku, but I don't want to make my secret keys public. I am deploying directly from a public github repo, so I don't want to include the service account file in the deployment.

I can take the service account json file, make each property an environment variable, add each of those variables to Heroku and deploy it. Everything works great (after authorizing the new Heroku domain on my firebase application), but is there a better way to do this? This works, but it was kind of a pain to do (copying and pasting each variable and moving it). Am I missing an easier way to do this?

Here is the change I am making. From this line where it is pulling the credentials from a file:

admin.initializeApp({   credential: admin.credential.cert('./path/firebase-service-account.json'),   databaseURL: "https://my-firebase-app.firebaseio.com" }); 

To this object that is bringing in all of the same things from environment variables:

admin.initializeApp({   credential: admin.credential.cert({     "type": process.env.FIREBASE_TYPE,     "project_id": process.env.FIREBASE_PROJECT_ID,     "private_key_id": process.env.FIREBASE_PRIVATE_KEY_ID,     "private_key": process.env.FIREBASE_PRIVATE_KEY,     "client_email": process.env.FIREBASE_CLIENT_EMAIL,     "client_id": process.env.FIREBASE_CLIENT_ID,     "auth_uri": process.env.FIREBASE_AUTH_URI,     "token_uri": process.env.FIREBASE_TOKEN_URI,     "auth_provider_x509_cert_url": process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,     "client_x509_cert_url": process.env.FIREBASE_CLIENT_X509_CERT_URL   }),   databaseURL: "https://my-firebase-app.firebaseio.com" }); 

Is this the best practice for deploying a firebase application with a service account to Heroku? I am using the dotenv node module to accomplish this.

like image 278
Luke Schlangen Avatar asked Dec 22 '16 15:12

Luke Schlangen


People also ask

How to deploy to Heroku with Firebase account key?

Here's a slightly different approach from the top answers I personally prefer to use when deploying apps to heroku that use firebase service accounts. Copy the contents from the service account key file as a JSON and set the GOOGLE_CREDS to take this value in your .env.

How do I add environment variables in Heroku?

Go to the settings tab of your Heroku app Go to Config Vars and click Reveal Config Vars Add the variables from the.env file as key-value pairs to the Config Vars of your app Heroku cannot read nor process.env files, so it will not be able to access your environment variables necessary for the deploying app.

How do I create a Heroku-app?

When logged in to the Heroku platform, you can create a new Heroku-app in the dashboard by clicking the New button. 3. Link your repository to Heroku You can link your codebase in several ways to your Heroku app: This means every time a commit is done to the master/main branch of the repository, the Heroku app will rebuild and re-deploy.

How do I use the firebase SDK for Cloud Functions?

The Firebase SDK for Cloud Functions offers built-in environment configuration to make it easy to store and retrieve this type of data for your project. To store environment data, you can use the firebase functions:config:set command in the Firebase CLI .


2 Answers

There's two three mandatory fields for the cert options object: clientEmail and privateKey (and now also projectId). Your example can be trimmed down to:

admin.initializeApp({   credential: admin.credential.cert({     "projectId": process.env.FIREBASE_PROJECT_ID,     "private_key": process.env.FIREBASE_PRIVATE_KEY,     "client_email": process.env.FIREBASE_CLIENT_EMAIL,   }),   databaseURL: "https://my-firebase-app.firebaseio.com" }); 

As an aside, some environments might have trouble with newlines in the private_key env var; I found key.replace(/\\n/g, '\n') to be a straightforward solution.

like image 50
Robert K. Bell Avatar answered Sep 19 '22 14:09

Robert K. Bell


  1. Convert the firebase config JSON (serviceAccountKey) to base64 encoded string, this can be done in many ways like using openssl command openssl base64 -in <firebaseConfig.json> -out <firebaseConfigBase64.txt> or using Nodejs as illustrated below
Buffer.from(JSON.stringify({   "type": "",   "project_id": "",   "private_key_id": "",   "private_key": "",   "client_email": "",   "client_id": "",   "auth_uri": "",   "token_uri": "",   "auth_provider_x509_cert_url": "",   "client_x509_cert_url": "" })).toString('base64') 
  1. Save the output base64 encoded string of the above step in an env variable like GOOGLE_CONFIG_BASE64. (Save it to ConfigVars in case of Heroku)
  2. Initialise the firebaseSdk in your node application
const firebaseAdminSdk = require('firebase-admin'),     firebaseAdminApp = firebaseAdminSdk.initializeApp({credential: firebaseAdminSdk.credential.cert(       JSON.parse(Buffer.from(process.env.GOOGLE_CONFIG_BASE64, 'base64').toString('ascii'))) }); 
like image 24
Huzaifa Iftikhar Avatar answered Sep 19 '22 14:09

Huzaifa Iftikhar