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.
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.
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.
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.
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 .
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.
openssl base64 -in <firebaseConfig.json> -out <firebaseConfigBase64.txt>
or using Nodejs as illustrated belowBuffer.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')
GOOGLE_CONFIG_BASE64
. (Save it to ConfigVars in case of Heroku)const firebaseAdminSdk = require('firebase-admin'), firebaseAdminApp = firebaseAdminSdk.initializeApp({credential: firebaseAdminSdk.credential.cert( JSON.parse(Buffer.from(process.env.GOOGLE_CONFIG_BASE64, 'base64').toString('ascii'))) });
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