38

I'm using Cloud Functions for Firebase with three different projects for development, testing and production purposes. Each project has a service-account.json. When I deploy the sources to an environment, the initialization looks like this:

var serviceAccount = require("./service-account-dev.json");

firebase.initializeApp({
    credential: firebase.credential.cert(serviceAccount),
    databaseURL: "https://nwDEV.firebaseio.com"
});

This is a bit difficult to handle, because I have to change the code everytime I want to deploy to a different environment. Is there a way to have an overall configuration, e.g. in firebase.json or.firebasesrc, which allows to integrate the service-account and decides on deployment which configuration to choose?

Otherwise is there a possibility to detect under which environment the code is running and to load the specific service-account.json and to set the databaseURL-property?

8
  • firebase.google.com/docs/functions/config-env Commented Apr 27, 2017 at 11:10
  • Okay, so there is no built-in alternative to manage different projects than setting an environment property in the CLI? Commented Apr 27, 2017 at 16:13
  • If you're deploying to different machines I would have thought you could just use an if-else based on the window.location. Commented Apr 27, 2017 at 16:20
  • 2
    Is there a reason you need to do service account auth instead of using the built-in auth for the admin SDK? This snippet shows how to use the Admin SDK to initialize for the currently deployed project automatically. If that doesn't work for you, can you clarify in the question why not? Commented Apr 27, 2017 at 18:13
  • 1
    @MichaelBleigh I'm using custom token because we are implementing SMS authentication. Commented Apr 28, 2017 at 10:08

3 Answers 3

28

You can use environment variables. https://firebase.google.com/docs/functions/config-env

  1. Select the project (you can use the command firebase projects:list to see them): firebase use my-project-development

  2. Set an environment variable firebase functions:config:set app.environment="dev"

  3. In your functions file, apply a conditional to choose the file: const serviceAccount = functions.config().app.environment === 'dev' ? 'credentials-dev.json' : 'credentials-prod.json';

Then you can use the file depending on the project:

firebase.initializeApp({
    credential: firebase.credential.cert(serviceAccount),
    databaseURL: "https://nwDEV.firebaseio.com"
});
Sign up to request clarification or add additional context in comments.

2 Comments

If it is node.js project, in most cases it uses process.env.NODE_ENV == 'production' But we can't change process.env of Firebase server so we have to use firebase functions:config:set some.key="value" as Diego's answer. This should be accepted answer.
And I prefer to use like this functions:config:set app.env="dev" or functions:config:set app.env="prd"
9

From what I understand of your question, what you are looking for boils down to a solution to translate the cloud functions you are deploying to the appropriate settings, i.e. production, development, and testing, which I assume means each of these is a unique project, and therefore database, in your Firebase environment.

If the above is true then the following should help.

Firebase Cloud Functions, and CLI more generally, is able to deploy to a specific project in your Firebase environment. To do this execute the following command in the terminal while in the cloud functions directory.

    $ firebase use --add

This will allow you to pick your additional project (for instance, development) and assign it an alias (I recommend "development" if it is as such). Then when deploying your functions you can choose which project (and therefore database) to deploy to by using the alias.

    $ firebase use default # sets environment to the default alias
    $ firebase use development # sets environment to the development alias

For more information please see: https://firebase.googleblog.com/2016/07/deploy-to-multiple-environments-with.html

One thing you may have to do for this to work would be to use the default config settings for Cloud Functions.

    $ admin.initializeApp(functions.config().firebase);

Comments

9

Short answer: the GCLOUD_PROJECT environment variable will be unique to your project, hence you can utilise it like this (sample code is for 2 different projects but you can extend it using switch or any other conditional statement):

const env = process.env.GCLOUD_PROJECT === 'my-app-prod' ? 'prod' : 'dev';

then use that env variable to load intended configuration.

Full example: (TypeScript)

  1. update .firebaserc file

    {
     "projects": {
        "default": "my-app-dev",
        "prod": "my-app-prod",
      }
     }
    
  2. create and modify your ./somewhere/config.ts file accordingly, let's say you're using AWS services (please ensure to secure your configuration details)

    export const config = {
      dev: {
        awsRegion: 'myDevRegion',
        awsAccessKey: 'myDevKey',
        awsSecretKey: 'myDevSecretKey'
      },
      prod: {
        awsRegion: 'myProdRegion',
        awsAccessKey: 'myProdKey',
        awsSecretKey: 'myProdSecretKey'
      }
    };
    
  3. now above items can be used in the index.ts file

    import { config } from './somewhere/config';
    import * as aws  from 'aws-sdk';
    . . .
    const env = process.env.GCLOUD_PROJECT === 'my-app-prod' ? 'prod' : 'dev';
    const awsCredentials = {
        region: config[env].awsRegion,
        accessKeyId: config[env].awsAccessKey,
        secretAccessKey: config[env].awsSecretKey
    };
    aws.config.update(awsCredentials);
    . . . 
    export const myFuncToUseAWS = functions....       
    
  4. Now the deployment

    Dev environment deployment: $ firebase deploy --only functions -P default

    Prod environment deployment: $ firebase deploy --only functions -P prod

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.