Firebaseapperror: failed to parse private key: error: invalid pem formatted message
Asked Answered
C

7

8

I got this error firebaseapperror: failed to parse private key: error: invalid pem formatted message when I pushed my nodejs app to heroku.

I had my environment variables all set like this

# .env file
    
project_id=project_id
private_key='-----BEGIN PRIVATE KEY----- ... ------END PRIVATE KEY-----\n'
client_email=client_email

And accessed them like so:

export const sa = {
    privateKey: process.env.private_key,
    projectId: process.env.project_id,
    clientEmail: process.env.client_email
};

On my local everything worked fine, but on production (heroku) I got the error mentioned above. The private key is a multiline environment variable and it couldn't be parsed.

Please, how do I fix this?

Centenarian answered 8/12, 2021 at 20:10 Comment(0)
C
18

The Fix

How I fixed this was through a post I saw online: How to Store a Long, Multi-line Private Key in an Environment Variable

Follow the step and you should fix this as well.

Brief summary of the post is this:

Store the long, multi-line key as a json string like this:

# .env file

project_id=project_id
private_key='{"privateKey": "-----BEGIN PRIVATE KEY----- ... ------END PRIVATE KEY-----\n"}'
client_email=client_email

Then parse it and destructure the key like this:

const { privateKey } = JSON.parse(process.env.private_key);

export const sa = {
    privateKey,
    projectId: process.env.project_id,
    clientEmail: process.env.client_email
};

This would work on local, but on production (heroku) you will get a parse error because of the single quote before and after the very key in question. Therefore, remove the single quotes before and after the key in your production env variable. I also tried without the single quote on local and it worked.

Extra Benefit

Extra Benefit with this Method

From this, you could even store the entire environment variables as one object like this

# .env file

sa='{"privateKey": "-----BEGIN PRIVATE KEY----- ... ------END PRIVATE KEY-----\n", "clientEmail": "client_email", "projectId": "project_id"}'

Then access it like this:

export const sa = JSON.parse(process.env.sa);

That's it.

Reminder: remember what I said about single quote!

Centenarian answered 8/12, 2021 at 20:10 Comment(1)
I
3

Don't use single/double quotes to store private key and then escape the \n characters while consuming

.env file

project_id=project_id
private_key=-----BEGIN PRIVATE KEY----- ... ------END PRIVATE KEY-----\n
client_email=client_email

Code-

const CERT = process?.env?.private_key?.replace(
  /\\n/g,
 '\n',
);
Ingenious answered 11/11, 2023 at 11:50 Comment(0)
M
2

If you are planning to use the private key by entering it in Vercel for example, what worked for me is remove all \n and quotes from your private key string. You don't need to JSON.parse!

If you have .env

PRIVATE_KEY ="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

You will notice there are a whole bunch of \n that does not seem necessary.
In fact they are not, so remove them all -----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----

Remove the double quotes too.

Add them to Vercel environment variables as a new variable.

use it like this.

admin.initializeApp({
  credential: admin.credential.cert({
    projectId: process.env.FIREBASE_PROJECT_ID,
    clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
    privateKey: process.env.PRIVATE_KEY,
  }),
})
Mixed answered 24/12, 2023 at 17:47 Comment(0)
D
1

Alternatively, getting rid of single/double quotes around private_key solved it in my case. You can set private key in your prod env variables as:

-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----
Disloyalty answered 20/11, 2022 at 12:21 Comment(0)
A
1

The most consistent result for me was to transform the json to base64 string and then JSON.parse(Buffer.from(process.env.CERT, 'base64').toString())

Agnola answered 5/12, 2022 at 2:57 Comment(0)
P
1

There should be \n not \n.

Not this

6","private_key":"-----BEGIN PRIVATE KEY-----\\nMIIEv

should be this

6","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEv

There will be many \n in RSA key, check for more

Parrisch answered 14/6, 2023 at 20:14 Comment(0)
N
0

For me, the issue was that \n was replaced by \n while storing the key in .env and setting it in environment variable in production environment.

Nickolas answered 12/6 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.