In the world of CI/CD, simpler is often better. While many blog posts offer complex GitHub Actions workflows for Firebase Functions deployment, I discovered that a more streamlined approach works perfectly well. In this article, I'll share a minimalist yet effective GitHub Actions workflow for deploying Firebase Functions, along with setup instructions and solutions for common issues you might encounter.
The Minimalist Workflow
Here's a clean, efficient GitHub Actions workflow for deploying Firebase Functions:
name: Deploy Firebase Functions
on:
push:
branches:
- master
jobs:
build_and_deploy:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '22'
- name: Install Dependencies
run: cd functions && npm install
- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy --only functions
env:
GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}
PROJECT_ID: ${{ secrets.GCLOUD_PROJECT }}
This workflow does exactly what's needed without unnecessary complexity:
- Triggers on pushes to the master branch
- Checks out the repo
- Sets up Node.js with the latest LTS version
- Installs dependencies for the functions directory
- Deploys only the functions to Firebase
Setup Instructions
1. Create the Workflow File
Create a .github/workflows
directory in your repository (if it doesn't exist already) and add a file named firebase-functions-deploy.yml
with the workflow content above.
2. Set Up GitHub Secrets
You'll need to add two secrets to your GitHub repository:
- GCP_SA_KEY: A service account key for Firebase deployment
- GCLOUD_PROJECT: Your Firebase project ID
To set up the GCP service account key:
- Go to the Google Cloud Console
- Navigate to IAM & Admin > Service Accounts
- Create a new service account or select an existing one
- Grant the account the "Firebase Admin" and "Cloud Functions Admin" roles
- Create a new JSON key for this service account
- Copy the entire JSON content and add it as the
GCP_SA_KEY
secret in your GitHub repository settings
For the GCLOUD_PROJECT
secret, simply add your Firebase project ID, which you can find in your Firebase console.
3. Configure firebase.json
Ensure your firebase.json
file is correctly configured. Here's a real-world example of a functions configuration:
{
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
]
}
This configuration:
- Specifies "functions" as the source directory
- Identifies it as the default codebase
- Lists files to ignore during deployment
- Runs linting and build commands before deployment
Your full firebase.json file might include other services (firestore, hosting, etc.), but the workflow in this article focuses just on deploying functions.
Common Pitfalls and Solutions
1. Incorrect firebase.json Configuration
If your deployment fails with errors like "Functions directory not found," check your firebase.json configuration. Make sure the "source" path correctly points to your functions directory.
2. Workflow Not Triggering
If your workflow isn't running when you push code, double check the branch name in your workflow file. The example uses master
, but your default branch might be named main
or something else. Make sure it matches your repository's primary branch.
3. Authentication and Permission Issues
If you see authentication errors, verify:
- Your GCP_SA_KEY contains the complete JSON service account key
- The PROJECT_ID secret matches your Firebase project ID exactly
A common pitfall is insufficient permissions for your service account. If you encounter permission errors in your workflow logs, you'll need to grant additional roles to your service account. For example:
Error: HTTP Error: 403, The caller does not have permission
When this happens:
- Check your workflow logs carefully to identify which specific permissions are missing
- Go to the Google Cloud Console IAM section
- Find your service account and grant only the necessary additional roles
- Follow the least-privilege principle - only grant what's absolutely required
Common roles needed for Firebase Functions deployment include:
- Firebase Admin (
roles/firebase.admin
) - Cloud Functions Admin (
roles/cloudfunctions.admin
) - Cloud Build Editor (
roles/cloudbuild.builds.editor
) - Service Account User (
roles/iam.serviceAccountUser
)
4. Node.js Version Compatibility
Firebase Functions might require specific Node.js versions. If you encounter compatibility issues, adjust the node-version
in the workflow to match what Firebase Functions supports (check Firebase documentation for the latest supported versions).
5. Dependencies Installation Failures
If npm install fails, check if you need to specify a working directory more precisely or if you need to install dependencies in the root directory as well.
Conclusion
While more complex workflows might be necessary for larger projects with multiple Firebase services, this streamlined approach works perfectly for most Firebase Functions deployments. By keeping your CI/CD workflow simple, you'll have fewer points of failure and an easier time troubleshooting when issues do arise.
Remember: in CI/CD, simplicity is a feature, not a bug. Happy deploying!