Firebase 無主機開發 2026 完全指南:從 Cloud Functions 到 App Hosting,少寫一行伺服器配置的工程美學

Firebase 無主機開發 2026 完全指南:從 Cloud Functions 到 App Hosting,少寫一行伺服器配置的工程美學

我前陣子聽到一個案例:某家 SaaS 公司用 Firebase 開發 MVP,產品起飛後幾個月,使用者來到 1,000 萬,月帳單從 $1,200 飆到 $30,000,而且沒有任何告警,直接收到一張五位數帳單。最後他們花了三個月把後端整個改寫到 Supabase,月帳單回到 $25 (Horizon Dev 2026 比較報告 )。

這個故事我不是要嚇你「Firebase 不能用」,而是想說:無主機(Serverless)這條路,不是只有 firebase deploy 就萬事 OK。

Firebase 在 2026 年仍然是 BaaS 領域最完整的方案之一——根據 Tech Insider 2026 對比報告Horizon Dev 比較 ,weekly npm downloads 約 320 萬,遙遙領先 Supabase 的 45 萬。但它的計費模式、Vendor Lock-in 風險、Firestore 與 SQL 思維的差異,每一項都可能讓沒做好功課的團隊吃苦頭。

這篇文章把官方文件、生產環境踩坑、2026 年最新定價、AI 整合(Genkit、Vertex AI)、和 Supabase 的最新對比通通整理在一起,讓你看完後能做出明確的架構決策——不只是「跟風用」,而是用得對、用得久、用得不爆預算

本文前置知識:你需要對 Node.js / TypeScript、基礎雲端概念(容器、CDN、CI/CD)有一定理解。文中所有規格與定價以 2026 年 5 月官方文件為準。


一、什麼是 Firebase 無主機?拆解五層核心服務

firebase-無主機-五層架構

「Serverless」字面意思是「沒有伺服器」,但這顯然不對——程式碼總得跑在某個地方。它的真正意涵是:伺服器的存在對你透明,你不用 SSH、不用 patch OS、不用設 nginx,雲端會在請求進來的瞬間動態分配資源,閒置時就回收。

Firebase 的無主機體系由五個核心組件構成:

組件 角色 主要負責
Cloud Functions for Firebase 運算層 執行後端邏輯、響應事件或 HTTPS 請求
Cloud Firestore / Realtime Database 資料層 NoSQL 儲存與多端即時同步
Firebase Authentication 安全層 註冊登入、社群登入、多因素驗證
Firebase Hosting / App Hosting 部署層 靜態託管、SSR 應用、CDN 分發
Cloud Storage for Firebase 儲存層 圖片、影片等大型檔案

從架構視角看,這五層的關係是這樣的:

[mermaid 圖表 — 原始 HackMD 版本可正常渲染]

flowchart LR Client[Web / Mobile Client] -->|HTTPS| Hosting[Firebase Hosting / App Hosting] Client -->|SDK| Auth[Firebase Authentication] Client -->|SDK + Rules| FS[Cloud Firestore] Client -->|SDK| Storage[Cloud Storage] Hosting --> CF[Cloud Functions] Auth -.事件.-> CF FS -.事件.-> CF Storage -.事件.-> CF CF --> FS CF --> Storage

最關鍵的設計選擇在於:客戶端 SDK 直接打資料庫,不需要中間人(傳統的後端 API 伺服器)。這帶來兩個極端:

  • 好處:開發者不用為每個 CRUD 寫 REST endpoint,前端工程師也能完成原本要兩個團隊才做得完的事
  • 壞處:所有的權限驗證、資料 schema 防護,全靠 Security Rules 來把關。寫不好就是巨大的安全洞

每一層都有自己的 know-how。我們從跑邏輯的 Cloud Functions 開始拆。


二、Cloud Functions 1st vs 2nd Gen:終於不用為冷啟動煩惱了

firebase-cloud-functions-1代vs2代

Cloud Functions for Firebase 在 2022 年底推出第二代(2nd Gen),但很多 2020 年前的 Firebase 專案到今天還在跑 1st Gen——這幾乎可以說是「在用古董機種」。兩代差異不只是版本號,根本是不同層級的東西。

規格對比

引用自 官方 Firebase 版本對比文件oneuptime 2026 v2 評測

規格 1st Gen 2nd Gen
HTTP timeout 9 分鐘(540s) 60 分鐘(3600s)
事件觸發 timeout 9 分鐘 9 分鐘
最大記憶體 8 GB 16 GiB(GA)
最多 vCPU 2 4(GA)
Concurrency 1 req/instance 預設 80,可設 1–1000
底層基礎 Cloud Functions 原生 Cloud Run + Eventarc
Min instances 支援 原生支援
Traffic splitting 不支援 支援

最關鍵的差異是 concurrency。在 1st Gen 中,每個實例只能處理一個請求——意思是當 50 個請求同時湧入,系統就得啟動 50 個新實例,每個都要付出冷啟動代價(約 100ms 到數秒)。

但在 2nd Gen 中,一個實例可以同時處理最多 1000 個請求 。這意味著突發 50 個請求完全不會觸發冷啟動——一個實例就吃下了。

程式碼遷移範例

從 1st Gen 改寫到 2nd Gen,import 路徑是關鍵:

// 1st Gen — 舊版
const functions = require("firebase-functions/v1");

exports.helloWorld = functions.https.onRequest((req, res) => {
  res.send("Hello from 1st Gen");
});
// 2nd Gen — 新版,加上 concurrency 設定
const { onRequest } = require("firebase-functions/v2/https");

exports.helloWorld = onRequest({
  concurrency: 500,         // 單一實例最多並行 500 請求
  minInstances: 1,          // 保持 1 個實例預熱,徹底消滅冷啟動
  cpu: 1,
  memory: "512MiB",
  timeoutSeconds: 60,
}, (req, res) => {
  res.send("Hello from 2nd Gen");
});

冷啟動三招實戰

冷啟動是無主機的「原罪」,但 2nd Gen 加上幾個技巧後幾乎可以忽略:

1. 設置 minInstances 對延遲敏感的函數(用戶登入、結帳),保留 1–2 個實例預熱。會多付一點錢,但首次請求延遲從 2 秒降到 50ms。

2. 延遲載入大型依賴 分析 Java Code Geeks 的 冷啟動深度報告 指出,JavaScript 函數的啟動時間幾乎全花在 require()/import

// ❌ 全域載入:每次冷啟動都吃 800ms
const { BigQuery } = require("@google-cloud/bigquery");

exports.report = onRequest((req, res) => {
  const bq = new BigQuery();
  // ...
});

// ✅ 路徑內載入:只有實際用到時才載入
exports.report = onRequest((req, res) => {
  if (req.path === "/heavy-report") {
    const { BigQuery } = require("@google-cloud/bigquery");
    const bq = new BigQuery();
    // ...
  }
});

3. 用 onInit() 推遲全域初始化 全域變數的初始化會在每次冷啟動時執行。把昂貴的初始化(連線池、SDK 客戶端)放進 onInit() hook,避免部署時 timeout。

Tip:1st Gen 還在運作,但 Google 已宣告 2025/02/18 起 1st Gen 強制使用 Artifact Registry 。新專案請直接從 2nd Gen 開始。


三、Firestore Security Rules:一張規則表救你十條 API

firebase-security-rules-安全層

無主機架構下最大的安全爭議是「客戶端直接打資料庫」。傳統後端有 middleware 把關,Firebase 用什麼擋?答案是 Security Rules——一套部署在伺服器端、客戶端完全無法竄改的宣告式語言。

基本語法範例

service cloud.firestore {
  match /databases/{database}/documents {
    
    // 用戶只能讀寫自己的個人資料
    match /users/{userId} {
      allow read, write: if request.auth != null
                         && request.auth.uid == userId;
    }
    
    // 任何登入者都能讀貼文,但只有作者能改/刪
    match /posts/{postId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null
                    && request.resource.data.authorId == request.auth.uid;
      allow update, delete: if request.auth != null
                            && resource.data.authorId == request.auth.uid;
    }
  }
}

性能限制:那條 10 次 get() 的紅線

這是 Firebase 老手才知道的坑。根據 官方規則條件文件 ,規則中跨文件查詢有嚴格上限:

  • 單一文件請求 / 查詢:最多 10 次 get()exists()
  • 批次寫入 / 交易:總計 20 次,但每個操作仍受 10 次限制
  • 超過任一上限 → permission denied error

舉個實際情境:

// ❌ 容易踩到 10 次上限的寫法
match /comments/{commentId} {
  allow create: if get(/databases/$(database)/documents/posts/$(request.resource.data.postId)).data.authorId == request.auth.uid
                || get(/databases/$(database)/documents/admins/$(request.auth.uid)).data.role == "moderator"
                || get(/databases/$(database)/documents/teams/$(get(...).data.teamId)).data.members.hasAny([request.auth.uid]);
}

這種「rule 裡面跑 SQL」的寫法會立刻觸發上限。**正確解法是把權限資訊放進 Custom Claims **:

// ✅ 直接讀 token 裡的 custom claim,零 get() 呼叫
match /comments/{commentId} {
  allow create: if request.auth.token.role in ["author", "moderator"];
}

註冊用戶時透過 Admin SDK 設定 claim:

import { getAuth } from "firebase-admin/auth";

await getAuth().setCustomUserClaims(uid, {
  role: "moderator",
  teamId: "team-42",
});
// 用戶下次 ID token 重新整理後就會帶上這些 claim

Tip:每個 get()/exists() 都會被計算為一次 Firestore read,會收費——即使規則最終拒絕了請求。把權限放進 token 不只解決 10 次限制,也省下一筆讀取費用。

Security Rules 的其他冷知識限制

來自 code.build 規則完整指南

  • 函數最多 7 個參數
  • 最多 10 個 let 變數
  • 函數呼叫深度上限 20
  • 單次請求最多評估 1000 個表達式
  • 不支援 loop / recursion

這些限制乍看很嚴苛,但其實是為了讓規則評估維持在納秒級。如果你發現規則寫不下了,那是訊號——你的資料模型該重新設計了。


四、突破單一文件 1 寫/秒:分片計數器實戰

firebase-firestore-分片計數器

Firestore 對單一文件的寫入頻率有個硬性限制:約每秒 1 次(受 官方 best practices 文件 證實)。對「按讚數」、「即時觀看人數」、「投票統計」這類場景,1 寫/秒根本不夠用。

解法是分片計數器(Distributed Counters):把一個邏輯計數器拆成 N 個分片,寫入時隨機選一個。

完整實作範例

以下程式碼基於 oneuptime 2026 distributed counters 實作教學

import { 
  doc, setDoc, updateDoc, getDocs, collection,
  increment, writeBatch, getFirestore 
} from "firebase/firestore";

const db = getFirestore();
const NUM_SHARDS = 10;

// 1️⃣ 初始化(只做一次)
async function createCounter(counterPath) {
  const batch = writeBatch(db);
  batch.set(doc(db, counterPath), { numShards: NUM_SHARDS });
  
  for (let i = 0; i < NUM_SHARDS; i++) {
    batch.set(doc(db, `${counterPath}/shards/${i}`), { count: 0 });
  }
  
  return batch.commit();
}

// 2️⃣ 寫入:隨機挑分片(每秒可達 NUM_SHARDS 次寫入)
async function incrementCounter(counterPath, amount = 1) {
  const shardId = Math.floor(Math.random() * NUM_SHARDS);
  const shardRef = doc(db, `${counterPath}/shards/${shardId}`);
  await updateDoc(shardRef, { count: increment(amount) });
}

// 3️⃣ 讀取:聚合所有分片
async function getCounterTotal(counterPath) {
  const shardsSnap = await getDocs(collection(db, `${counterPath}/shards`));
  let total = 0;
  shardsSnap.forEach(snap => { total += snap.data().count; });
  return total;
}

// 使用範例
await createCounter("counters/post-123-likes");
await incrementCounter("counters/post-123-likes");
const likes = await getCounterTotal("counters/post-123-likes");

寫入吞吐 vs 讀取成本的取捨

[mermaid 圖表 — 原始 HackMD 版本可正常渲染]

flowchart TB subgraph Write[寫入路徑] W1[Client 1] -->|increment| S0[Shard 0] W2[Client 2] -->|increment| S5[Shard 5] W3[Client 3] -->|increment| S9[Shard 9] end

subgraph Read[讀取路徑]
    R[Client] -->|read all shards| Agg[Aggregate Sum]
    Agg --> Total[Total Count]
end

S0 -.summed.-> Agg
S5 -.summed.-> Agg
S9 -.summed.-> Agg</div>
分片數 最大寫入吞吐 單次讀取成本
10 10 寫/秒 10 reads
100 100 寫/秒 100 reads
1000 1000 寫/秒 1000 reads

明顯地,分片越多寫得越快,但每讀一次總和就要付 N 次 read 的錢。對讀多寫多的場景(社群媒體按讚),可以加一個 roll-up Cloud Function,定期把所有分片加總寫到一個單一的「rollup 文件」:

import { onSchedule } from "firebase-functions/v2/scheduler";
import { getFirestore } from "firebase-admin/firestore";

// 每分鐘聚合一次
export const rollupCounters = onSchedule("every 1 minutes", async () => {
  const db = getFirestore();
  const counterRef = db.doc("counters/post-123-likes");
  const shards = await counterRef.collection("shards").get();
  
  let total = 0;
  shards.forEach(doc => { total += doc.data().count; });
  
  await counterRef.update({ rollupTotal: total, rollupAt: new Date() });
});

前端只讀 counterRef 一次(1 read)就拿到接近即時的總數。


五、App Hosting vs Firebase Hosting:你該用哪個?

firebase-app-hosting-vs-hosting

Firebase 在 2024 年中推出了 App Hosting,是給現代全端框架(Next.js、Angular、Astro)用的下一代託管方案。它和原本的 Firebase Hosting 差別很大,選錯會踩坑。

差異全表

引用 Firebase 官方部落格 App Hosting vs Hosting

維度 Firebase Hosting(原版) Firebase App Hosting(2024+)
適用場景 靜態網站 / SPA 全棧 SSR / API routes
Framework 感知 部分(透過 web frameworks 實驗) 原生 framework-aware
SSR 後端 Cloud Functions Cloud Run(直接)
建置流程 Firebase CLI Cloud Native Buildpacks
動態擴展 透過 Functions 原生 Cloud Run scale-to-zero
GitHub 整合 PR Preview Channels 原生 Git push 部署

何時該用哪個?

用 Firebase Hosting(原版)的情況

  • 純前端 SPA(React、Vue、Svelte)
  • 靜態文件網站(部落格、Marketing site)
  • 需要極致 CDN 邊緣快取的場景

用 App Hosting 的情況

  • Next.js 13+(App Router、Server Components)
  • Angular 17+ SSR
  • 需要 API routes / middleware 的應用
  • 想要 GitHub push 自動部署的工作流

Hosting 整合 GitHub 的「Git push 即部署」

執行 firebase init hosting:github 後,CLI 會幫你做這幾件事:

  1. 在 GCP 建立具部署權限的服務帳號
  2. 加密 JSON 金鑰並上傳到 GitHub Secrets
  3. 產生 YAML workflow,每個 PR 都會獲得獨立預覽 URL
  4. PR 合併到 main 後自動上線

對小團隊來說,這幾乎就是免費的 CI/CD pipeline,比起自己刻 GitHub Actions + AWS S3 簡單太多。


六、真實成本計算:Blaze、Supabase、VPS 三方對戰

firebase-成本對比-blaze-supabase-vps

成本是工程主管最關心的話題。我把 2026 年三方最新定價整理在一起,讓你看清楚不同規模下的真實差異。

Firebase Blaze 定價(2026/05)

引用自 Firebase 官方定價頁Tekpon 2026 計算彙整

Firestore(資料層)

項目 Spark 免費 Blaze 計費
Reads 50K / 天 $0.06 / 100K
Writes 20K / 天 $0.18 / 100K
Deletes 20K / 天 $0.02 / 100K
儲存 1 GB $0.108–$0.026 / GB(階梯)

Cloud Functions(運算層)

項目 Spark 免費 Blaze 計費
Invocations 2M / 月 $0.40 / 1M
GB-seconds 400K / 月 隨資源量計

Hosting / Storage(部署與儲存層)

項目 Spark 免費 Blaze 計費
Hosting 頻寬 10 GB / 月 $0.15 / GB(cached)、$0.20 / GB(uncached)
Storage 流量 $0.15 / GB egress
Auth phone SMS $0.01–$0.06 / SMS

2026/02/03 重大變更Firebase Cloud Storage 現在強制需要 Blaze 計畫 ——即使你的用量在免費額度內。新專案如果只想用 Spark 計畫,得避開 Cloud Storage。

三種規模情境模擬

情境 A:MVP(1,000 DAU)

項目 Firebase Supabase VPS(DigitalOcean)
月費 $0(Spark 涵蓋) $0(Free tier) $5–$20(固定)
維運人力 $0 $0 工程師 20% 工時
小計 $0 $0 $5 + 人力

情境 B:成長期(10,000 DAU、50K API/天)

項目 Firebase Supabase VPS
Firestore / DB $30 $0 $10(VPS DB)
Functions $15 $0 $0
Hosting + Storage $10 $0 $5
小計 $55 $25(Pro 固定) $25 + 人力

情境 C:規模化(10M DAU、read-heavy)

項目 Firebase Supabase VPS
資料庫 $500–$1,500 $200–$400 自管成本高
Functions / Edge $300–$800 含於 Pro 自管
小計 $1,000–$3,000 $200–$600(3–5 倍便宜) 複雜

數據驗證:Tech Insider 2026 對比Horizon Dev 客戶案例 都指出 read-heavy 場景下 Supabase 比 Firebase 便宜 3–5 倍。

流量定價特別警告

如果你的應用是影音串流大量檔案下載,Firebase Hosting 的 $0.20/GB egress 是個大坑。對比 GPU Per Hour 2026 egress 對比

平台 Egress 單價(per TB)
Cloudflare R2 $0(!)
Supabase $90
Google Cloud $120
Vercel $150
Firebase $200
Netlify $550

對流媒體類產品,把靜態大檔案放 Cloudflare R2 + Firebase 處理動態邏輯是常見的混合架構。


七、生產踩坑:四個你絕對會遇到的問題

firebase-生產踩坑-警示

讀完官方文件就能寫出生產級應用的時代結束了。我把這四年看過的真實踩坑案例整理成四類——每一條都是某個團隊用真金白銀換來的教訓。

踩坑 1:把 SDK 滲透到業務邏輯(最深的鎖定)

// ❌ 業務邏輯直接呼叫 Firebase SDK
async function getUser(userId: string) {
  const snap = await getDoc(doc(db, "users", userId));
  return snap.data();
}
// ✅ 透過 Repository pattern 抽象
interface UserRepository {
  findById(id: string): Promise<User | null>;
}

class FirestoreUserRepository implements UserRepository {
  async findById(id: string) {
    const snap = await getDoc(doc(db, "users", id));
    return snap.exists() ? (snap.data() as User) : null;
  }
}

// 業務層只依賴介面
async function getUser(userId: string, repo: UserRepository) {
  return repo.findById(userId);
}

未來要遷到 Supabase / PostgreSQL 時,你只要新寫一個 PostgresUserRepository,業務層完全不動。

踩坑 2:把 Firestore 當 SQL 用(N+1 帳單炸彈)

// ❌ 渲染一個貼文列表,每篇貼文額外查作者 → N+1 reads
const posts = await getDocs(collection(db, "posts")); // 1 read × 100 = 100 reads
for (const post of posts.docs) {
  const author = await getDoc(doc(db, "users", post.data().authorId)); // 100 reads
}
// 結果:渲染一個列表 = 200 reads,1000 個用戶看一次 = 200,000 reads
// ✅ 去規範化:把作者基本資訊存進貼文
// 寫入時:
await addDoc(collection(db, "posts"), {
  title: "...",
  content: "...",
  authorId: user.uid,
  authorName: user.displayName,    // 冗餘
  authorAvatar: user.photoURL,     // 冗餘
});

// 讀取時:1 query 就拿到全部
const posts = await getDocs(collection(db, "posts")); // 100 reads only

「寧可複製 100 次小資料,也不要查 100 次資料庫」——這是 Firestore 的鐵律。

踩坑 3:全域初始化過載 → 部署 timeout

// ❌ 模組載入時就執行昂貴邏輯
import { GoogleAuth } from "google-auth-library";
const auth = new GoogleAuth({ /* ... */ });
const token = await auth.getAccessToken(); // 部署時就會跑 → timeout

export const myFunction = onRequest((req, res) => { /* ... */ });
// ✅ 用 onInit hook 推遲到實例真正啟動時
import { onInit } from "firebase-functions/v2/core";

let auth: GoogleAuth;
onInit(async () => {
  auth = new GoogleAuth({ /* ... */ });
});

export const myFunction = onRequest((req, res) => {
  // 在這裡 auth 已經初始化完成
});

踩坑 4:Security Rules 跨多文件 get() 觸發 10 次上限

承前面 Section 3 的範例,多層權限檢查很容易爆表。永遠優先用 Custom Claims,而不是寫巢狀 get()

Q&A 補充:規則 deploy 後生效要多久?根據 zeriflow 安全最佳實踐 ,rules deployment 是原子操作,幾秒鐘內生效。但 client SDK 端可能因為網路快取延遲到 1 分鐘。生產部署時務必先在 Emulator Suite 跑完整測試。


八、AI 時代的 Firebase:Genkit 與 Vertex AI 整合

firebase-genkit-ai-整合

2026 年的 Firebase 已經不只是 BaaS——它正快速成為 AI 應用的後端首選。從 Firebase 在 Cloud Next 2026 的官方公告 加上社群觀察,三個值得注意的動向:

Genkit:開源 AI 應用框架

Genkit 是 Google Firebase 團隊推出的開源 AI 框架,支援 JS / Go / Python,提供統一介面接 Google、OpenAI、Anthropic、Ollama 等模型。

import { genkit, z } from "genkit";
import { googleAI } from "@genkit-ai/googleai";

const ai = genkit({
  plugins: [googleAI()],
  model: "googleai/gemini-2.5-flash",
});

export const summarize = ai.defineFlow(
  {
    name: "summarize",
    inputSchema: z.string(),
    outputSchema: z.string(),
  },
  async (text) => {
    const { text: summary } = await ai.generate(`Summarize: ${text}`);
    return summary;
  }
);

flows 可以直接部署到 Cloud Functions / Cloud Run,所有 Telemetry 自動匯出到 Firebase Console。

Firebase AI Logic + Vertex AI

Firebase AI Logic 讓你直接從客戶端呼叫 Gemini 系列模型,免去自架 API Gateway。配合 App Check 確保只有你的 App 能呼叫。

最新支援的模型:

  • gemini-2.5-flashgemini-2.5-flash-lite(生產推薦)
  • imagen-4.0-generate-001imagen-4.0-fast-generate-001imagen-4.0-ultra-generate-001
  • gemini-live-2.5-flash-native-audio(即時音訊)

注意 gemini-2.0-flash 系列將於 2026/06/01 停用,要遷到 2.5。

Google AI Studio + Firestore 全棧 = 自然語言寫 App

Cloud Next 2026 最重磅的更新是:Google AI Studio 現在直接整合 Firestore + Authentication ,可以用自然語言生成包含後端的全棧應用。底層用 Cloud Run 跑 server code,Security Rules 也能自動草擬。

對小型專案而言,這幾乎是「Vibe Coding」的終極形式。


九、決策清單:你該選 Firebase 還是 Supabase?

這個選擇沒有單一答案——同一家公司不同產品線可能要選不同方案。我把它拆成三個維度去問:你的產品在哪個階段?技術需求是什麼?規模有多大?

產品階段

階段 建議 理由
MVP / 概念驗證 Firebase Auth、即時同步、CDN 開箱即用,可用免費額度撐 1–3 個月
已有 PMF、開始規模化 開始監控成本曲線 設定預算告警、檢視單頁 read 數
大規模生產(>100K DAU) 重新評估 視 read/write 比例、流量類型決定是否遷移

技術需求

需求 建議
重度 mobile(iOS/Android/Flutter) Firebase(離線快取、FCM 推播無人能敵)
即時協作(聊天、Google Docs 級即時同步) Firebase(Firestore listeners)
複雜報表、多表 JOIN、聚合查詢 Supabase / PostgreSQL
AI Agent 應用 Firebase + Genkit
大檔案下載 / 流媒體 混合架構(Firebase + Cloudflare R2

抽象層保險策略

無論最後選誰,在程式碼中保留抽象層是必做的。

// 把所有資料存取藏在 interface 後面
export interface DataStore {
  users: UserRepository;
  posts: PostRepository;
  // ...
}

// 啟動時注入具體實作
const store: DataStore = useFirebase
  ? new FirebaseDataStore(db)
  : new SupabaseDataStore(supabaseClient);

短期多寫一兩百行,長期省下你半年重構時間。


結語:不是不寫伺服器,是把伺服器寫進雲端基因

「無主機」聽起來像逃避,但它真正的意思是把伺服器的存在問題交給雲端、把心力放回業務邏輯上。

Firebase 在 2026 年做到的事情比 5 年前多太多了——2nd Gen Functions 解決了冷啟動、App Hosting 把 Next.js 部署簡化到極致、Genkit 讓 AI 應用三行 code 就能跑、AI Studio 開始能用自然語言寫全棧。

但你也看到了它的代價:Firestore 不是 SQL、Security Rules 有硬性上限、Egress 流量比同行貴一倍、Vendor Lock-in 風險真實存在。

回到開頭那家月帳單從 $1,200 飆到 $30,000 的 SaaS 公司——他們事後復盤發現,問題不是 Firebase「壞」,而是他們從第一天起就沒有任何抽象層,沒設預算告警,把 Firestore 當 PostgreSQL 用,列表頁觸發 N+1 reads。等到使用者破百萬,每多一個用戶就是一張帳單。

如果你正在開新專案,我會說:直接用 Firebase,但是寫 Repository 介面、設 Budget Alert、用 Custom Claims這三件事,請在第一週就做完。它們加起來不過半天工,能幫你避開 90% 的後悔。

無主機從來不是「免費的午餐」。它是一份你必須懂得怎麼吃的合約——讀懂它,你就能用一半的時間做出原本兩倍規模才做得出的產品。


延伸閱讀


這篇對你有幫助嗎? 如果你正在評估技術選型、或處理 Firebase 帳單失控的問題,歡迎留言分享你的踩坑經驗。下一篇我會寫「Firebase → Supabase 實戰遷移指南」,帶你看真實案例怎麼把 Firestore 結構翻譯成 PostgreSQL schema、Security Rules 改寫成 RLS。


本文最初發布於 HackMD @BASHCAT

留言

這個網誌中的熱門文章

Arduino 課本可能沒教的事(1)

SI4432 搭配Arduino

燒錄 Arduino mini Pro 燒錄