Firebase Hosting 是 Google Firebase 平台里的静态 + 边缘层。它把文件分发到全球 CDN,自动配 SSL,并且能和 Firebase 的 Auth、Firestore、Cloud Functions 联动。它不是 Vercel 那种 Next.js 运行时,把它当成 Next.js host 用是新手踩坑的主要原因。下面给出正确心智模型、基础 firebase.json 和上线命令。
问题背景
Firebase Hosting 2016 年发布,从最初的”只能托管静态文件”逐步加上了”通过 rewrite 调用 Cloud Functions / Cloud Run”。到 2026 年它的定位有点尴尬:比纯对象存储能干,但又远不如框架原生平台顺手。正确的心智模型是:“一个会调用你后端的 CDN”,不是”Next.js 运行时”。
判断标准
- 你已经用了 Firebase Auth、Firestore 或 Cloud Functions,想合并账单。
- 你的站点是纯静态 HTML、SPA,或者 Astro 静态构建——不是重度 SSR 应用。
- 你想要免费的 SSL 和全球 CDN,不想自己折腾配置。
- 你需要 preview channel 分享分支给客户看。
- 你不需要每个请求都在边缘做服务端渲染。
快速结论
如果你的技术栈已经是 Firebase,或者站点本身就是静态的,那 Firebase Hosting 合适。想要开箱即用的 Next.js SSR 就别选它——那是 Vercel 的强项。
开始前准备
- 有 Firebase 项目(Console 创建或
firebase projects:create)。 - 装好 Node 和
firebase-tools(npm install -g firebase-tools)。 - 静态 build 产物就绪(
dist/、out/、build/)。
实操步骤
-
确认输出是静态。 目录里有
index.html、资源目录、按路由的子目录。如果产物是 Node server(Next.js SSR 没静态导出),重新考虑 Firebase Hosting。 -
装 CLI、登录:
npm install -g firebase-tools
firebase login
firebase projects:list
- 项目里初始化 hosting:
firebase init hosting
# ? Public directory? dist
# ? Configure as a single-page app? No (静态站 / Astro: No)
# ? Set up automatic builds and deploys with GitHub?(可选)
- 静态内容站的基础
firebase.json:
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"trailingSlash": true,
"headers": [
{
"source": "/_astro/**",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "**/*.html",
"headers": [
{ "key": "Cache-Control", "value": "no-cache, max-age=0" }
]
},
{
"source": "**/*.@(jpg|jpeg|png|webp|avif|svg|woff2)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=2592000" }
]
}
]
}
}
- rewrite 决策:
{
"hosting": {
"rewrites": [
{ "source": "/api/**", "function": "api" },
{ "source": "/render/**", "run": { "serviceId": "ssr-render", "region": "us-central1" } }
]
}
}
只在需要 SPA index.html 兜底时用 ** → /index.html——内容站千万别用,会把真实 404 全压成 200。
- build + deploy:
npm run build
firebase deploy --only hosting
# Hosting URL: https://your-project.web.app
- 无痕 + curl 验证:
curl -sI https://your-project.web.app/ | grep -i cache-control
curl -sI https://your-project.web.app/this-does-not-exist/ | head -1
# 期望 HTTP/2 404(不是 200)
- 加自定义域名。 Firebase Console → Hosting → Add custom domain → 按提示配 DNS(典型是两条 A 记录到 Firebase anycast IP,加 www 的 CNAME)。SSL 自动签。
执行检查清单
public与 framework 输出目录一致。- HTML 与 hashed 资源的缓存头分别显式配置。
- 内容站没有误用
**→/index.htmlrewrite。 - 自定义域名绿勾、SSL 有效。
- Deploy 释放有迹可循(Hosting → Release history)。
上线后验证
curl -sI显示预期缓存头。- 故意访问不存在路径返回 404,不是 200。
*.web.app和自定义域提供完全相同内容。firebase hosting:channel:deploy能产出可分享的 preview URL。
容易踩的坑
- 把 Firebase Hosting 当 Next.js host 用——SSR 是能通过 Cloud Functions 跑,但远不如 Vercel 顺。
- 忘了配
cleanUrls或 trailing slash 规则,部署完到处 404。 - 让 HTML 用默认缓存(1 小时),然后纳闷为什么内容没更新。
- public 目录配错了——经常配成源码目录而不是 build 产物。
- 不小心加了 SPA 兜底 rewrite——所有 URL 都返回首页。
FAQ
- Firebase Hosting 免费吗?: Spark 免费档相当慷慨:10 GB 存储、每日 360 MB 流量,对绝大多数独立站够用。
- Firebase Hosting 支持 SSR 吗?: 通过把请求 rewrite 到 Cloud Function 或 Cloud Run 间接支持,不是一等公民。
- 可以只用 Hosting 不用其它 Firebase 服务吗?: 可以。纯静态站完全没问题。不过这样做的人最后大多会后悔——不如直接选框架原生平台。
- 会自动有 HTTPS 吗?: 会。默认
*.web.app域名和自定义域名都通过 Let’s Encrypt 拿到免费 SSL。 - 部署出问题怎么回滚?: Hosting 保留 release history。
firebase hosting:clone或 console 里点 Rollback。