Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 420
Jason Berryman Avatar asked Feb 16 '18 21:02

Jason Berryman


People also ask

Does Firebase Auth use JWT?

The custom JWT returned from your server can then be used by a client device to authenticate with Firebase (iOS+, Android, web). Once authenticated, this identity will be used when accessing other Firebase services, such as the Firebase Realtime Database and Cloud Storage.


1 Answers

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();
like image 173
Jen Person Avatar answered Oct 05 '22 20:10

Jen Person