53

I use .env variables in my app.js file to access the keys. Everything was working fine until I downloaded a new Firebase Service Account Private Key. When I replaced the old value with the new value I can no longer access the key because in terminal when I run node app.js I keep getting an error message:

/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/auth/credential.js:129 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse private key: ' + error); ^

Error: Failed to parse private key: Error: Invalid PEM formatted message. at FirebaseAppError.FirebaseError [as constructor] (/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/utils/error.js:39:28) at FirebaseAppError.PrefixedFirebaseError [as constructor] (/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/utils/error.js:85:28) at new FirebaseAppError (/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/utils/error.js:119:28) at new Certificate (/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/auth/credential.js:129:19) at new CertCredential (/Users/Cpu/Desktop/...../node_modules/firebase-admin/lib/auth/credential.js:192:64) at Object.cert (/Users/Cpu/Desktop/.....) at Object. (/Users/Cpu/Desktop/...../app.js:14:32) at Module._compile (module.js:571:32) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:488:32) at FirebaseAppError.FirebaseError [as constructor] npm ERR! code ELIFECYCLE npm ERR! errno 1

All I did was c+p the new Private Key and then added it and saved the .env file, pushed to heroku, and it's no longer working. I even downloaded a new Private Key but the same problem occurs.

The old and new Private Keys

// old Private Key
-----BEGIN PRIVATE KEY-----\nbbbbbbbb\n-----END PRIVATE KEY-----\n

// new Private Key
-----BEGIN PRIVATE KEY-----\nzzzzzzzz\n-----END PRIVATE KEY-----\n

The .env file:

FIREBASE_PROJECT_ID=wwwwwwww
FIREBASE_CLIENT_EMAIL=xxxxxxxx
FIREBASE_DATABASE_URL=yyyyyyyy
FIREBASE_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\nzzzzzzzz\n-----END PRIVATE KEY-----\n

The app.js file:

const dotenv = require('dotenv');
dotenv.load();

var admin = require("firebase-admin");
admin.initializeApp({
  credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,   // I get no error here
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,   // I get no error here
      privateKey: process.env.FIREBASE_PRIVATE_KEY   // I get error HERE
  }),
  databaseURL: process.env.FIREBASE_DATABASE_URL
});

How can I fix this issue?

Lance Samaria
  • 14,568
  • 10
  • 83
  • 201

4 Answers4

175

The problem was since I used dotenv variables inside the .env file the FIREBASE_PRIVATE_KEY had escaping characters: \n inside of it.

I had to follow this answer and append .replace(/\\n/g, '\n') to the end of it to parse it:

privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n')

So now the code looks like:

admin.initializeApp({
  credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID, // I get no error here
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL, // I get no error here
      privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n') // NOW THIS WORKS!!!
  }),
  databaseURL: process.env.FIREBASE_DATABASE_URL
});
Lance Samaria
  • 14,568
  • 10
  • 83
  • 201
  • 1
    I'm having this problem after creating new keys in Firebase. I'm keeping the key values in Firebase Environmental Variables, so I shouldn't have to adjust for `\n`. When I `firebase deploy --only functions`, I get the PEM error. Any suggestions? – Chadd Nov 05 '18 at 19:26
  • I never user Firebase env vars before. I wish I could help – Lance Samaria Nov 05 '18 at 19:52
  • This solved my issue. Strange thing was it worked without it, then suddenly stopped working. Anyway, voted this up for others to see. – Patrick Michaelsen Dec 01 '18 at 05:43
  • @PatrickMichaelsen the same exact thing happened to me. It was working without it then for some strange after I changed to a new private key and tried again it no longer worked. Very odd. Anyway glad I could help and thanks for the upvote. Cheers! – Lance Samaria Dec 01 '18 at 05:45
  • Thank you! Works perfectly with firebase config variables. e.g accessing functions.config().var.name.replace(/\\n/g, '\n') (set via firebase functions:config:set var.name="xxx" ). – The Geek Oct 28 '19 at 17:41
  • I had to add: .replace(/\\\\n/g, '\n') in order to replace the //n correctly – Adnan Erkocevic Jul 07 '20 at 08:47
  • 2
    I had same situation on AWS elastic beanstalk, I added `\\n` instead of `\n` in the environment variables and added replace where I access them. – Abishek Kumar Jul 17 '20 at 12:30
  • after many days and nights I finally have success. I send you my deepest gratitudes – Jeff Voss Jan 26 '22 at 23:12
  • had same problem, used the raplce but also had to add \n to the very start of the key – Alexander Hemming Feb 28 '22 at 19:05
35

You must add your key into double qoutes to allow expanded new lines option according with dotenv documentation.

You can check that option at Rules section in dotenv github.

https://github.com/motdotla/dotenv#rules

  FIREBASE_PROJECT_ID=wwwwwwww
  FIREBASE_CLIENT_EMAIL=xxxxxxxx
  FIREBASE_DATABASE_URL=yyyyyyyy
  FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nzzzzzzzz\n-----END PRIVATE KEY-----\n"
Bryan Ramirez
  • 351
  • 3
  • 3
0

I believe cert function is wating JSON object try converting the key into JSON and i think it will work

credential: admin.credential.cert(JSON.parse(serviceAccountKey))

this worked for me !

  • 1
    it shows SyntaxError: Unexpected token o in JSON at position 1 – Piyush Pandey Mar 13 '20 at 10:02
  • 1
    @PiyushPandey I had the same issue. I'm using dotenv and I was requiring dotenv after the file i was using it in, so that fixed it for me. Might be unhelpful, but just letting you know that's what did it for me! – Akash Kundu Jan 07 '21 at 01:14
-3

Generate admin SDK Firebase under Firebase > Settings > Admin SDK Firebase. Go to Google Cloud Platform in your project, click in IAM administrator > Source account, and generate the key code in account service (your account service is generated in the admin SDK Firebase).

Jeremy Caney
  • 6,191
  • 35
  • 44
  • 70