Handle special case of application default credentials location by yinzara · Pull Request #444 · firebase/firebase-admin-node
This doesn't need to be this complex. You only have to modify the first if block in the existing constructor. Rest of the constructor can remain unchanged. Something like:
constructor(httpAgent?: Agent) {
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
this.credential_ = credentialFromFile(process.env.GOOGLE_APPLICATION_CREDENTIALS, httpAgent);
return;
}
// Rest is unchanged
}
function credentialFromFile(filePath: string, httpAgent?: Agent): Credential {
const credentialsFile = readCredentialFile(filePath);
if (typeof credentialsFile !== 'object') {
throw new FirebaseAppError(
AppErrorCodes.INVALID_CREDENTIAL,
'Failed to parse contents of the credentials file as an object',
);
}
if (credentialsFile.type === 'service_account') {
return new CertCredential(credentialsFile, httpAgent);
}
if (credentialsFile.type === 'authorized_user') {
return new RefreshTokenCredential(credentialsFile, httpAgent);
}
throw new FirebaseAppError(
AppErrorCodes.INVALID_CREDENTIAL,
'Invalid contents in the credentials file',
);
}
function readCredentialFile(filePath: string): {[key: string]: any} {
if (typeof filePath !== 'string') {
throw new FirebaseAppError(
AppErrorCodes.INVALID_CREDENTIAL,
'Failed to parse credentials file: TypeError: path must be a string',
);
}
let fileText: string;
try {
fileText = fs.readFileSync(filePath, 'utf8');
} catch (error) {
throw new FirebaseAppError(
AppErrorCodes.INVALID_CREDENTIAL,
`Failed to read credentials from file ${filePath}: ` + error,
);
}
try {
return JSON.parse(fileText);
} catch (error) {
throw new FirebaseAppError(
AppErrorCodes.INVALID_CREDENTIAL,
'Failed to parse contents of the credentials file as an object: ' + error,
);
}
}