Jamgreen
Jamgreen

Reputation: 11059

Deploy environment variables to Firebase hosting

I use Firebase in React and when initializing Firebase, I use environment variables fetched from my .env file with dotenv. I want to build and deploy my React app to Firebase hosting, I use GitHub Actions with the following .yml workflow file:

name: Deploy
on:
  push:
    branches:
      - master

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Install Dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Archive Production Artifact
        uses: actions/upload-artifact@master
        with:
          name: public
          path: public
  deploy:
    name: Deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: public
      - name: Deploy
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

However, my build step fails (i.e. npm run build) because the environment variables are not found. If I hardcode the values instead of using my environment variables, the workflow is successful.

Do I need to do add my environment variables to GitHub secrets similar to how I added FIREBASE_TOKEN in my deploy step and add them to the workflow to be something like:

name: Deploy
on:
  push:
    branches:
      - master

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Install Dependencies
        run: npm install
      - name: Build
        run: npm run build
        env:
          FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }}
          FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }}
          FIREBASE_DATABASE_URL: ${{ secrets.FIREBASE_DATABASE_URL }}
          FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }}
          FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }}
          FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }}
          FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
      - name: Archive Production Artifact
        uses: actions/upload-artifact@master
        with:
          name: public
          path: public
  deploy:
    name: Deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: public
      - name: Deploy
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

I receive the same error, saying that it can't find the API token.

When I browse workflow files in other firebase-based React apps, I can't see anyone adding these environment variables like I have suggested. What is the proper way of handling environment variables in apps deployed to Firebase? Do they belong in the build or deploy step?

Upvotes: 14

Views: 8133

Answers (3)

Nikita Kalganov
Nikita Kalganov

Reputation: 641

Correct, you should add your env parameters to Github Secrets (https://github.com/your-project-name/settings/secrets/actions) and address them in YAML file, setting them up in the beginning of the file. Here's an example:

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
env:
  REACT_APP_API_KEY: ${{ secrets.REACT_APP_API_KEY }}
  REACT_APP_FIREBASE_AUTH_DOMAIN: ${{ secrets.REACT_APP_FIREBASE_AUTH_DOMAIN }}
  REACT_APP_FIREBASE_PROJECT_ID: ${{ secrets.REACT_APP_FIREBASE_PROJECT_ID }}
  REACT_APP_FIREBASE_STORAGE_BUCKET: ${{ secrets.REACT_APP_FIREBASE_STORAGE_BUCKET }}
  REACT_APP_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.REACT_APP_FIREBASE_MESSAGING_SENDER_ID }}
  REACT_APP_FIREBASE_APP_ID: ${{ secrets.REACT_APP_FIREBASE_APP_ID }}
  REACT_APP_FIREBASE_MEASUREMENT_ID: ${{ secrets.REACT_APP_FIREBASE_MEASUREMENT_ID }}
  REACT_APP_FIREBASE_DATABASE_URL: ${{ secrets.REACT_APP_FIREBASE_DATABASE_URL }}

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [17.4.0]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
        
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3      
        with:
          node-version: ${{ matrix.node-version }}
      - run: |
              npm install
              npm ci && npm run build --if-present      
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_APPNAME }}'
          channelId: live
          projectId: APPNAME

Upvotes: 2

Kaveen M.
Kaveen M.

Reputation: 145

Instead of adding a .env file you can easily add the secrets to github secrets.

enter image description here

Once the secrets are added to github secrets you can add them to env at the build process as follow in your workflow.

name: Firebase Deployment
on:
  push:
    branches:
      - master
      - feature/secrets_fix

env:
  API_KEY: ${{ secrets.FIREBASE_API_KEY }}
  APP_ID: ${{ secrets.FIREBASE_APP_ID }}
  AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }}
  MESSAGE_SENDER_ID: ${{ secrets.FIREBASE_MESSAGE_SENDER_ID }}
  PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }}
  STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }}
  TOKEN: ${{ secrets.FIREBASE_TOKEN }}

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/[email protected]
      - name: Install Dependencies
        run: npm install
      - name: Build
        env:
          CI: false
        run: npm run build
      - name: Archive Production Artifact
        uses: actions/upload-artifact@v2
        with:
          name: build
          path: build
  deploy:
    name: Deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/[email protected]
      - name: Download Artifact
        uses: actions/download-artifact@v2
        with:
          name: build
          path: build
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

secrets.${YOUR_GITHUB_SECRET_NAME} Once they are mapped as above under env, you can easily retrieve them from react application using process.env.YOUR_ENV_VARIABLE_NAME_HERE

Following is a example on firebaseConfig

const firebaseConfig = {
    apiKey: process.env.API_KEY,
    authDomain: process.env.AUTH_DOMAIN,
    projectId: process.env.PROJECT_ID,
    storageBucket: process.env.STORAGE_BUCKET,
    messagingSenderId: process.env.MESSAGE_SENDER_ID,
    appId: process.env.APP_ID
};

Hope this will help someone.

Upvotes: 3

Kuncheria
Kuncheria

Reputation: 1930

Your custom env variables must start with REACT_APP_. Any other variables except NODE_ENV will be ignored to avoid accidentally exposing a private key on the machine that could have the same name. Please take a look at this article Adding Custom Environment Variables.

As an additional note you can also run the npm run build along with your env variables passed as parameters like this:

REACT_APP_FIREBASE_APIKEY=${{ secrets.REACT_APP_FIREBASE_APIKEY }} REACT_APP_FIREBASE_AUTHDOMAIN=${{ secrets.REACT_APP_FIREBASE_AUTHDOMAIN }} REACT_APP_FIREBASE_DBURL=${{ secrets.REACT_APP_FIREBASE_DBURL }} npm run build

Upvotes: 6

Related Questions