1414 * limitations under the License.
1515 */
1616
17+ import fs = require( 'fs' ) ;
1718import { deepExtend } from './utils/deep-copy' ;
1819import { AppErrorCodes , FirebaseAppError } from './utils/error' ;
1920import { AppHook , FirebaseApp , FirebaseAppOptions } from './firebase-app' ;
@@ -32,8 +33,18 @@ import {Database} from '@firebase/database';
3233import { Firestore } from '@google-cloud/firestore' ;
3334import { InstanceId } from './instance-id/instance-id' ;
3435
36+ import * as validator from './utils/validator' ;
37+
3538const DEFAULT_APP_NAME = '[DEFAULT]' ;
3639
40+ /**
41+ * Constant holding the environment variable name with the default config.
42+ * If the environmet variable contains a string that starts with '{' it will be parsed as JSON,
43+ * otherwise it will be assumed to be pointing to a file.
44+ */
45+ export const FIREBASE_CONFIG_VAR : string = 'FIREBASE_CONFIG' ;
46+
47+
3748let globalAppDefaultCred : ApplicationDefaultCredential ;
3849let globalCertCreds : { [ key : string ] : CertCredential } = { } ;
3950let globalRefreshTokenCreds : { [ key : string ] : RefreshTokenCredential } = { } ;
@@ -59,12 +70,20 @@ export class FirebaseNamespaceInternals {
5970 /**
6071 * Initializes the FirebaseApp instance.
6172 *
62- * @param {FirebaseAppOptions } options Options for the FirebaseApp instance.
73+ * @param {FirebaseAppOptions } options Optional options for the FirebaseApp instance. If none present
74+ * will try to initialize from the FIREBASE_CONFIG environment variable.
75+ * If the environmet variable contains a string that starts with '{'
76+ * it will be parsed as JSON,
77+ * otherwise it will be assumed to be pointing to a file.
6378 * @param {string } [appName] Optional name of the FirebaseApp instance.
6479 *
6580 * @return {FirebaseApp } A new FirebaseApp instance.
6681 */
67- public initializeApp ( options : FirebaseAppOptions , appName = DEFAULT_APP_NAME ) : FirebaseApp {
82+ public initializeApp ( options ?: FirebaseAppOptions , appName = DEFAULT_APP_NAME ) : FirebaseApp {
83+ if ( typeof options === 'undefined' ) {
84+ options = this . loadOptionsFromEnvVar ( ) ;
85+ options . credential = new ApplicationDefaultCredential ( ) ;
86+ }
6887 if ( typeof appName !== 'string' || appName === '' ) {
6988 throw new FirebaseAppError (
7089 AppErrorCodes . INVALID_APP_NAME ,
@@ -227,6 +246,36 @@ export class FirebaseNamespaceInternals {
227246 }
228247 } ) ;
229248 }
249+
250+ /**
251+ * Parse the file pointed to by the FIREBASE_CONFIG_VAR, if it exists.
252+ * Or if the FIREBASE_CONFIG_ENV contains a valid JSON object, parse it directly.
253+ * If the environmet variable contains a string that starts with '{' it will be parsed as JSON,
254+ * otherwise it will be assumed to be pointing to a file.
255+ */
256+ private loadOptionsFromEnvVar ( ) : FirebaseAppOptions {
257+ let config = process . env [ FIREBASE_CONFIG_VAR ] ;
258+ if ( ! validator . isNonEmptyString ( config ) ) {
259+ return { } ;
260+ }
261+ try {
262+ let contents ;
263+ if ( config . startsWith ( '{' ) ) {
264+ // Assume json object.
265+ contents = config ;
266+ } else {
267+ // Assume filename.
268+ contents = fs . readFileSync ( config , 'utf8' ) ;
269+ }
270+ return JSON . parse ( contents ) as FirebaseAppOptions ;
271+ } catch ( error ) {
272+ // Throw a nicely formed error message if the file contents cannot be parsed
273+ throw new FirebaseAppError (
274+ AppErrorCodes . INVALID_APP_OPTIONS ,
275+ 'Failed to parse app options file: ' + error ,
276+ ) ;
277+ }
278+ }
230279}
231280
232281
@@ -354,12 +403,15 @@ export class FirebaseNamespace {
354403 /**
355404 * Initializes the FirebaseApp instance.
356405 *
357- * @param {FirebaseAppOptions } options Options for the FirebaseApp instance.
406+ * @param {FirebaseAppOptions } [options] Optional options for the FirebaseApp instance.
407+ * If none present will try to initialize from the FIREBASE_CONFIG environment variable.
408+ * If the environmet variable contains a string that starts with '{' it will be parsed as JSON,
409+ * otherwise it will be assumed to be pointing to a file.
358410 * @param {string } [appName] Optional name of the FirebaseApp instance.
359411 *
360412 * @return {FirebaseApp } A new FirebaseApp instance.
361413 */
362- public initializeApp ( options : FirebaseAppOptions , appName ?: string ) : FirebaseApp {
414+ public initializeApp ( options ? : FirebaseAppOptions , appName ?: string ) : FirebaseApp {
363415 return this . INTERNAL . initializeApp ( options , appName ) ;
364416 }
365417
0 commit comments