Joel Hager
Joel Hager

Reputation: 3440

How can I tell firebase if I'm in development or production? (For firebase functions sandbox/live switch)

I have some firebase functions that I test locally, but I really don't want to have to rely on remembering to switch a flag, or explicitly set the values. Is there a value I can check in firebase to tell if it's in dev or prod? I'm also using NextJS, so I don't mind changing it on the next side either. Just whatever way makes the most sense within the firebase ecosystem. Thanks!

The invocation of client inside my function (on firebase):

const env = new checkoutNodeSDK.core.SandboxEnvironment(clientId, clientSecret)

My firebase.js file:

import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/firestore'
import 'firebase/functions'
const dev = true


export const app = !firebase.apps.length ? firebase.initializeApp({
  apiKey: "REDACTED",
  authDomain: "edit-elements.firebaseapp.com",
  databaseURL: "https://edit-elements-default-rtdb.firebaseio.com",
  projectId: "edit-elements",
  storageBucket: "edit-elements.appspot.com",
  messagingSenderId: "340652433701",
  appId: "1:340652433701:web:a26472592c1538bbac7acc",
  measurementId: "G-945XC7348K"
}) : firebase.app()

const auth = app.auth()
const db = app.firestore()
const functions = app.functions()
if (process.env.NODE_ENV === 'development') {
  functions.useEmulator('localhost', 5001)
  db.useEmulator('localhost', 8080)
}
export { auth, db, functions }

I want to set something like:

const env = flagDev ? new checkoutNodeSDK.core.SandboxEnvironment(clientId, clientSecret) : new checkoutNodeSDK.core.LiveEnvironment(clientId, clientSecret)

TL;DR - When the function is called in dev, I want the function to use the Sandbox credentials. In prod, I want to use the live sandbox credentials.

Upvotes: 3

Views: 3428

Answers (1)

samthecodingman
samthecodingman

Reputation: 26206

If the intention is to detect whether the currently running Cloud Function is being emulated or not, you can check the FUNCTIONS_EMULATOR environment variable.

const isEmulated = process.env.FUNCTIONS_EMULATOR === "true";

However, as Doug stated, you shouldn't trust this value blindly. While it has a value now and works, this is an undocumented environment variable used internally by the Firebase Emulator Suite.

The best course of action is to use a different PROJECT_ID entirely for your local environment and only deploy to your production project when all is well.

To get your PROJECT_ID being used for the active Cloud Function, use:

const PROJECT_ID = JSON.parse(process.env.FIREBASE_CONFIG).projectId;

Then assuming you have a TEST_PROJECT_ID and PROD_PROJECT_ID, you can now check if you are in production using:

const isProduction = PROJECT_ID === PROD_PROJECT_ID;

When testing on your system, you should use TEST_PROJECT_ID:

firebase use TEST_PROJECT_ID

And once you've green-lit the changes, you can deploy to PROD_PROJECT_ID:

firebase deploy --project PROD_PROJECT_ID

You can also add these project IDs to .firebaserc:

{
  "projects": {
    "default": "TEST_PROJECT_ID",
    "TEST": "TEST_PROJECT_ID",
    "PROD": "PROD_PROJECT_ID"
  }
}

Inside of your main project directory, create a package.json file:

{
  "name": "my-firebase-project",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "main": "",
  "scripts": {
    "deploy": "firebase deploy -P PROD"
  },
  "keywords": [],
  "author": "You",
  "license": "NONE"
}

Add the same "deploy" script to your functions/package.json:

"scripts": {
  "deploy": "firebase deploy -P PROD"
}

Now when you want to deploy to production, you use: firebase deploy -P PROD or npm run deploy.

Make sure when editing your Functions Configuration (functions.config() values), you set them on both TEST_PROJECT_ID and PROD_PROJECT_ID with the appropriate keys.

There are a number of environment variables available to executing Cloud Functions, but only those included by Google Cloud and Firebase have guaranteed values:

Key Description Note
FUNCTION_TARGET Reserved: The function to be executed.
FUNCTION_SIGNATURE_TYPE Reserved: The type of the function: http for HTTP functions, and event for event-driven functions.
K_SERVICE Reserved: The name of the function resource. Replaces FUNCTION_NAME in legacy code
K_REVISION Reserved: The version identifier of the function.
PORT Reserved: The port over which the function is invoked.
FIREBASE_CONFIG Reserved: Firebase project configuration JSON-encoded string

Upvotes: 9

Related Questions