Firebase Hosting

Web HostingSPAPWAFirebaseGoogleServerlessCDN

Web Hosting Platform

Firebase Hosting

Overview

Firebase Hosting is a fast and secure web hosting service provided by Google. Optimized for SPAs and PWAs, it supports full-stack development through integration with other Firebase services. Popular for web applications linked with mobile app development, valued for rapid prototype development through integration with Firebase Authentication, Firestore, etc.

Details

Provided as part of Firebase acquired by Google in 2014, Firebase Hosting is a hosting service specialized for modern web application development. Utilizing Google's global CDN network, it achieves high-speed delivery from over 180 locations worldwide. Particularly optimized for SPAs (Single Page Applications) and PWAs (Progressive Web Apps), it provides automatic SSL certificates, custom domains, and rollback functionality as standard. Through tight integration with Firebase Authentication, Cloud Firestore, Cloud Functions, etc., it provides complete solutions from frontend to backend.

Advantages and Disadvantages

Advantages

  • High-Speed Global CDN: Delivery from Google's 180+ edge locations
  • Firebase Ecosystem Integration: Complete integration with Authentication, Firestore, Functions, etc.
  • SPA/PWA Optimization: Features specialized for modern web applications
  • Automatic SSL Certificates: Free SSL via Let's Encrypt
  • Easy Rollback: One-click restoration to previous versions
  • Real-time Features: Live updates combined with Firebase Realtime
  • Free Usage Tier: Up to 10GB monthly storage and transfer for free

Disadvantages

  • Google Dependency: High dependency on Google services
  • Limitations: Increased billing with large files or high traffic
  • High Learning Curve: Understanding of entire Firebase ecosystem required
  • Server-side Limitations: Constraints beyond static sites and Cloud Functions

Reference Pages

Code Examples

Basic Setup and Project Configuration

# Install Firebase CLI
npm install -g firebase-tools

# Login to Firebase
firebase login

# Initialize project
firebase init hosting

# Local development server
firebase serve --only hosting --port 5000

# Start emulators (all features)
firebase emulators:start
// firebase.json - Firebase configuration
{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/api/**",
        "function": "api"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [
      {
        "source": "/service-worker.js",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache"
          }
        ]
      },
      {
        "source": "**/*.@(jpg|jpeg|gif|png|svg|webp)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=31536000"
          }
        ]
      }
    ],
    "cleanUrls": true,
    "trailingSlash": false
  },
  "functions": {
    "source": "functions",
    "node": 18
  },
  "emulators": {
    "hosting": {
      "port": 5000
    },
    "functions": {
      "port": 5001
    },
    "firestore": {
      "port": 8080
    },
    "ui": {
      "enabled": true,
      "port": 4000
    }
  }
}

Static Site Deployment

# Production deployment
firebase deploy --only hosting

# Deploy with preview channel
firebase hosting:channel:deploy preview-feature

# Deploy to specific project
firebase deploy --project my-project-id

# Multi-site management
firebase target:apply hosting main my-main-site
firebase target:apply hosting admin my-admin-site
firebase deploy --only hosting:main
# .github/workflows/firebase.yml - GitHub Actions
name: Deploy to Firebase Hosting

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
        
      - name: Deploy to Firebase Hosting
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}'
          projectId: my-project-id
          channelId: live

Framework Integration (Next.js, React, Vue)

// next.config.js - Next.js + Firebase
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  trailingSlash: true,
  images: {
    unoptimized: true
  },
  
  // Firebase Hosting configuration
  assetPrefix: process.env.NODE_ENV === 'production' ? undefined : '',
  
  // Environment variables configuration
  env: {
    FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID,
    FIREBASE_API_KEY: process.env.FIREBASE_API_KEY,
  },
};

module.exports = nextConfig;
<!-- Vue.js + Firebase integration -->
<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
      <button v-if="user" @click="logout">Logout</button>
      <button v-else @click="login">Login</button>
    </nav>
    
    <main>
      <router-view />
    </main>
  </div>
</template>

<script>
import { auth } from './firebase/config';
import { signInWithPopup, GoogleAuthProvider, signOut } from 'firebase/auth';

export default {
  name: 'App',
  data() {
    return {
      user: null
    };
  },
  
  created() {
    auth.onAuthStateChanged(user => {
      this.user = user;
    });
  },
  
  methods: {
    async login() {
      const provider = new GoogleAuthProvider();
      try {
        await signInWithPopup(auth, provider);
      } catch (error) {
        console.error('Login failed:', error);
      }
    },
    
    async logout() {
      try {
        await signOut(auth);
      } catch (error) {
        console.error('Logout failed:', error);
      }
    }
  }
};
</script>
// firebase/config.ts - Firebase initialization
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getFunctions } from 'firebase/functions';
import { getStorage } from 'firebase/storage';

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
};

// Firebase initialization
const app = initializeApp(firebaseConfig);

// Service initialization
export const auth = getAuth(app);
export const db = getFirestore(app);
export const functions = getFunctions(app);
export const storage = getStorage(app);

export default app;

Custom Domains and SSL

# Add custom domain
firebase hosting:sites:create my-custom-site
firebase target:apply hosting main my-custom-site

# Domain configuration
firebase hosting:sites:list
firebase hosting:sites:get my-custom-site

# SSL certificates are automatically configured (Let's Encrypt)
// firebase.json - Multi-site configuration
{
  "hosting": [
    {
      "target": "main",
      "public": "dist",
      "rewrites": [
        {
          "source": "**",
          "destination": "/index.html"
        }
      ]
    },
    {
      "target": "admin",
      "public": "admin-dist",
      "rewrites": [
        {
          "source": "/admin/**",
          "destination": "/admin/index.html"
        }
      ]
    }
  ]
}
// .firebaserc - Project configuration
{
  "projects": {
    "default": "my-project-id",
    "staging": "my-project-staging",
    "production": "my-project-prod"
  },
  "targets": {
    "my-project-id": {
      "hosting": {
        "main": ["my-main-site"],
        "admin": ["my-admin-site"]
      }
    }
  }
}

Serverless Functions and APIs

// functions/index.js - Cloud Functions
const { onRequest } = require('firebase-functions/v2/https');
const { onDocumentCreated } = require('firebase-functions/v2/firestore');

// HTTP API endpoint
exports.api = onRequest({
  cors: true,
  region: 'asia-northeast1'
}, async (req, res) => {
  const { method, path } = req;
  
  if (method === 'GET' && path === '/users') {
    // Get user list from Firestore
    const admin = require('firebase-admin');
    const db = admin.firestore();
    
    try {
      const snapshot = await db.collection('users').get();
      const users = [];
      snapshot.forEach(doc => {
        users.push({ id: doc.id, ...doc.data() });
      });
      
      res.json({ users });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  } else {
    res.status(404).json({ error: 'Not found' });
  }
});

// Firestore trigger
exports.onUserCreate = onDocumentCreated('users/{userId}', (event) => {
  const snapshot = event.data;
  const data = snapshot.data();
  
  console.log(`New user created: ${data.name}`);
  
  // Welcome email sending process, etc.
  return null;
});
// src/services/api.ts - Frontend API client
import { getFunctions, httpsCallable } from 'firebase/functions';
import { functions } from '../firebase/config';

class ApiService {
  private functions = getFunctions();

  // HTTP Callable Function
  async getUsers() {
    try {
      const getUsersFunction = httpsCallable(this.functions, 'getUsers');
      const result = await getUsersFunction();
      return result.data;
    } catch (error) {
      console.error('Error fetching users:', error);
      throw error;
    }
  }

  // REST API call
  async fetchUserData(userId: string) {
    try {
      const response = await fetch(`/api/users/${userId}`);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      return await response.json();
    } catch (error) {
      console.error('Error fetching user data:', error);
      throw error;
    }
  }

  // Real-time data listening
  subscribeToUserUpdates(userId: string, callback: (data: any) => void) {
    const { doc, onSnapshot } = require('firebase/firestore');
    const { db } = require('../firebase/config');
    
    const userDoc = doc(db, 'users', userId);
    return onSnapshot(userDoc, callback);
  }
}

export const apiService = new ApiService();

CI/CD and Production Optimization

# .github/workflows/firebase-preview.yml - Preview channel
name: Firebase Preview Deploy

on:
  pull_request:
    branches: [ main ]

jobs:
  build_and_preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
        
      - name: Deploy to Preview Channel
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}'
          projectId: my-project-id
          expires: 7d
        id: firebase_preview
        
      - name: Comment Preview URL
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🔥 Preview URL: ${{ steps.firebase_preview.outputs.details_url }}'
            })
# Firebase CLI command collection
firebase projects:list                    # List projects
firebase use --add                        # Add project
firebase hosting:sites:list               # List sites
firebase hosting:channel:list             # List channels

# Logs and monitoring
firebase functions:log                     # Functions logs
firebase hosting:clone source-site-id destination-site-id  # Clone site

# Security rules
firebase deploy --only firestore:rules    # Firestore rules
firebase deploy --only storage:rules      # Storage rules

# Database operations
firebase firestore:delete --all-collections  # Delete all data (caution)
firebase firestore:indexes                # Index management

# Performance optimization
firebase hosting:disable                  # Disable hosting
firebase experiments:enable webframeworks # Experimental features
// firebase.json - Advanced configuration
{
  "hosting": {
    "public": "dist",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    
    // PWA configuration
    "rewrites": [
      {
        "source": "/sw.js",
        "destination": "/sw.js"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    
    // Security headers
    "headers": [
      {
        "source": "**",
        "headers": [
          {
            "key": "Strict-Transport-Security",
            "value": "max-age=31536000; includeSubDomains"
          },
          {
            "key": "X-Content-Type-Options",
            "value": "nosniff"
          }
        ]
      }
    ],
    
    // Redirect configuration
    "redirects": [
      {
        "source": "/old-page",
        "destination": "/new-page",
        "type": 301
      }
    ],
    
    // A/B testing configuration
    "appAssociation": "AUTO",
    "cleanUrls": true,
    "trailingSlash": false
  },
  
  // Remote Config
  "remoteconfig": {
    "template": "remoteconfig.template.json"
  },
  
  // App Distribution
  "appDistribution": {
    "serviceAccountFile": "path/to/service-account.json",
    "releaseNotesFile": "RELEASE_NOTES.md"
  }
}