Jason Berryman
Jason Berryman

Reputation: 4898

Authenticating with the Firebase Admin SDK using environment variable

The problem

When I try to use an environment variable to authenticate with Cloud Firestore, I get an ENAMETOOLONG error. I've searched so many places for documentation. If anyone can point me in the right direction, that'd be useful.

Creating the environment variable

I've created an environment variable to load my service account key

export MY_CREDENTIALS=$(cat myGoogleServiceAccountKey.json)

My code

const admin = require('firebase-admin');

var serviceAccount = process.env.MY_CREDENTIALS;
// console.log(`Service account = ${serviceAccount}`);

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
});

const db = admin.firestore();

The error

When I run a node script which fetches my serviceaccount key from my environment variables, I get the following error:

/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/auth/credential.js:142
            throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse certificate key file: ' + error);
            ^

Error: Failed to parse certificate key file: Error: ENAMETOOLONG: name too long, open '{
  "type": "service_account",
  "project_id": "myProject",
  "private_key_id": "123456789012345678901234567890",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMy private key\n-----END PRIVATE KEY-----\n",
  "client_email": "[email protected]",
  "client_id": "12345678901234567890",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-myProject.iam.gserviceaccount.com"
}'
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/utils/error.js:39:28)
    at FirebaseAppError.PrefixedFirebaseError [as constructor] (/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/utils/error.js:85:28)
    at new FirebaseAppError (/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/utils/error.js:119:28)
    at Function.Certificate.fromPath (/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/auth/credential.js:142:19)
    at new CertCredential (/home/jason/Downloads/projects/myProjecte/functions/node_modules/firebase-admin/lib/auth/credential.js:192:45)
    at Object.cert (/home/jason/Downloads/projects/myProject/functions/node_modules/firebase-admin/lib/firebase-namespace.js:237:58)
    at Object.<anonymous> (/home/jason/Downloads/projects/myProject/myScript.js:7:34)
    at Module._compile (module.js:577:32)
    at Object.Module._extensions..js (module.js:586:10)

Upvotes: 19

Views: 11461

Answers (1)

Jen Person
Jen Person

Reputation: 7546

So when looking at the error you get, I notice it says Error: ENAMETOOLONG: name too long, open '{. When the admin.credential.cert function is passed a string, it assumes you're trying to open a file with that string name. If you cast that to an object, then it should be able to read the credentials.

const admin = require('firebase-admin');

var serviceAccount = process.env.MY_CREDENTIALS;
// console.log(`Service account = ${serviceAccount}`);

admin.initializeApp({
    credential: admin.credential.cert(JSON.parse(serviceAccount))
});

const db = admin.firestore();

Upvotes: 49

Related Questions