Firebase Hosting 绑定自定义域名(2026 实操)

把域名指向 Firebase Hosting:确切的 TXT、A、AAAA 记录与 dig 验证命令,外加 Needs setup 死循环和 SSL 卡住的修法。

Firebase Hosting 默认给你一个免费的 *.web.app 域名。要把站点放到 yourbrand.com 上,需要在控制台加域名、用 TXT 记录证明所有权,再用 A(和 AAAA)记录把流量指过来。顺序对了大概 15 分钟加 DNS 传播就好;顺序错了,可能盯着一个永远不变成 “Connected” 的 “Needs setup” 标签耗一下午。下面的记录和 dig 检查就是两者的分水岭。

免费的 Spark 套餐就能用,且允许商用站点,SSL 证书由 Let’s Encrypt 免费签发。截至 2026 年 6 月,Firebase 通过 Fastly 边缘网络分发自定义域名,所以下文几个失败场景会提到 Fastly 报错。

一句话结论

在 Firebase 加域名 → 加 TXT 记录并等它解析出来 → 点 Verify → 加上 Firebase 给的两条 A 记录(以及 AAAA 记录)。动手前先把所有指向旧 host 的 A/AAAA/CNAME 残留全删掉,否则 SSL 永远签不出来。TXT 记录要一直留着——Firebase 续期证书时还会再读它。

适合谁

  • *.web.app 已经能打开,现在想换成品牌域名。
  • 域名在某个 registrar 手里(Cloudflare、Namecheap、Porkbun、Squarespace 等)。
  • 你能接受手动改 DNS——全程只有这一步是手动的。
  • 你希望 apex(yourbrand.com)和 www 都能解析,而不是只有一个。
  • 需要免费 SSL,不需要通配证书(Firebase Hosting 不签通配证书)。

Quick setup 还是 Advanced setup

“Add custom domain” 向导有两种模式,选错是常见的时间黑洞:

模式适用做什么
Quick setup新域名,或没有在意的线上流量一次性验证所有权并给出 A 记录;可接受短暂中断
Advanced setup域名已在跑生产流量先验证所有权、签发证书,最后才让你切 A 记录,全程没有 SSL 空窗

迁移线上站点就选 Advanced setup。它把流程拆成所有权、证书、流量三步,访客不会撞上还没签发的证书。

开始前准备

  • 切换前至少 24 小时把现有 DNS 记录的 TTL 调到 300 秒,让旧解析快点过期。
  • 把所有指向旧 host 的 A、AAAA、CNAME 记录删掉。只要有冲突记录在,Firebase 就签不出证书。
  • 把 Firebase 项目 ID 和目标域名准备好。

实操步骤

  1. Firebase 控制台加域名。 Console → Hosting → Add custom domain → 输入 yourbrand.com。Quick setup 会给一条 TXT 验证记录,值是项目独有的;Advanced setup 用 hosting-site=[你的-site-id] 这种形式:
Host:  @  (或 yourbrand.com)
Type:  TXT
Value: hosting-site=your-site-id        (照抄 Firebase 显示的确切值)
TTL:   300
  1. 在 registrar 那边加 TXT。 Cloudflare API 写法,方便复用:
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
  -H "Authorization: Bearer $CF_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "type": "TXT",
    "name": "@",
    "content": "hosting-site=your-site-id",
    "ttl": 300
  }'
  1. 点 Verify 前先确认 TXT 已传播。 Firebase 给最多 24 小时让记录扩散,但通常几分钟就好:
dig +short TXT yourbrand.com @1.1.1.1
# "hosting-site=your-site-id"
  1. 点 Verify。 之后 Firebase 会给出把 apex 指向其边缘的 A 记录。截至 2026 年 6 月,官方文档里的示例 IP 是 199.36.158.100;控制台会显示两条地址,而且这些值可能变动,所以照抄控制台给的值,别写死:
Host:  @          Type: A      Value: 199.36.158.100
Host:  @          Type: A      Value: 199.36.158.101

想同时支持 IPv6,就把控制台列出的对应 AAAA 记录也加上(文档示例是 2620:0:890::100)。www 子域可以用 CNAME 指向你的 Hosting 站点,也可以用同样的 A/AAAA:

Host:  www        Type: CNAME  Value: your-project.web.app
  1. 加完 A/AAAA(或 CNAME)后,用两个解析器验证:
dig +short A yourbrand.com @1.1.1.1
# 199.36.158.100
# 199.36.158.101

dig +short A yourbrand.com @8.8.8.8        # 换第二个解析器交叉验证
dig +short CNAME www.yourbrand.com @1.1.1.1
# your-project.web.app.

如果返回里出现旧 host 的额外 IP,把那些残留记录删掉。DNS 会在好坏目标之间轮询,访问就会飘忽。

  1. 等状态变成 “Connected”。 SSL 自动签发,从 A 记录解析生效算起通常几小时内、最多 24 小时。用 curl 探证书:
curl -vI https://yourbrand.com 2>&1 | grep -E 'subject:|issuer:|HTTP'
# subject: CN=yourbrand.com
# issuer: C=US, O=Let's Encrypt, CN=...
# HTTP/2 200
  1. 加第二个变体。 先加了 apex,现在加 www(反之亦然)。Firebase 会给它签证书,并自动建一条 301 跳转到你的主域。

  2. 无痕窗口确认跳转:

curl -sI http://yourbrand.com       | head -2
# HTTP/1.1 301 Moved Permanently
# Location: https://yourbrand.com/

curl -sI https://www.yourbrand.com  | head -2
# HTTP/2 301
# location: https://yourbrand.com/   (如果 apex 是主域)
  1. 更新 Search Console、sitemap、canonical 标签。 新域名以 Domain property 验证后,重新提交 sitemap,让 Google 抓到新的主域。

上线检查清单

  • TXT 验证记录还在(永久保留,用于证书续期)。
  • A/AAAA 或 CNAME 在至少两个解析器(@1.1.1.1@8.8.8.8)下返回正确。
  • 没有残留任何指向旧 host 的 A/AAAA/CNAME 记录。
  • SSL 证书的 subject 与目标域名匹配,用 curl -vI 确认。
  • apex 和 www 都在 Firebase Hosting 注册了:一个主域,一个 301。
  • 新域名在 Search Console 以 Domain property 验证。
  • 浏览器或 Lighthouse 测一下没有 mixed content 警告。

容易踩的坑

  • 加了 A 记录却跳过 TXT。 验证会一直 pending。重新照抄 TXT 值,并用 dig +short TXT 确认。
  • 指向旧 host 的 A 或 AAAA 没删。 只要有冲突记录,Firebase 就签不出证书,且 DNS 会同时返回两个目标。检测:dig +short A(以及 dig +short AAAA)返回多余地址。
  • 在 apex 上用 CNAME。 多数 registrar 不允许。改用 A 记录,或 Cloudflare 的 CNAME flattening。
  • 只注册 apex 或只注册 www 然后丢掉另一个变体的流量。
  • registrar 那边 DNS 缓存重。 清缓存,或等调低的 TTL 过期。
  • 上线后把 TXT 删了。 Firebase 续期证书时会再读它,留着别动。
  • SSL 还没签发就开 Cloudflare 代理(“橙云”)。 先把记录设成 “DNS only”(灰云),让 Firebase 签完证书,再开回代理。
  • “Needs setup” 死循环。 2026 年 2 月有一个有记录的案例:域名在 “Needs setup”、“Custom domain has been set up”、“Certificate provisioning” 之间反复打转,即便 DNS 完全正确,线上 URL 仍返回 Fastly 的 “unknown domain” 错误。如果 DNS 已验证、标签却始终不稳定,在控制台把这个自定义域名删掉再重新添加,通常能解开卡死状态。

FAQ

  • SSL 多久签发? 通常一小时内,按 Firebase 文档上限最多 24 小时,从 A 记录解析生效算起。24 小时还没好就重查 DNS,并删掉任何冲突的 A/AAAA 记录。
  • apex 还是 www 当主域? 截至 2026 年 6 月,大多数独立站把 apex 当主域。选一个,全站(Search Console、sitemap、rel="canonical" 标签)保持一致,另一个 301 过去。
  • TXT 记录真得一直留着? 是的。它不是一次性所有权校验——Firebase 会持续读这条 hosting-site TXT 记录来授权 SSL 续期,删了可能让下次续期失败。
  • 能从另一个 host 无缝迁移吗? 能。先把现有记录 TTL 调成 300 秒,用 Firebase preview channel 验证新配置没问题,再切记录。想要零 SSL 空窗,就用 Advanced setup,让证书在切流量之前签发好。
  • 记录加完了为什么还显示 “needs setup”? 要么 DNS 还没传播,要么记录值和控制台给的不完全一致。重新照抄并用 dig 验证。如果 DNS 没问题循环还在,看上面坑里的 Fastly “Needs setup” 那条。
  • 同一个域名 Vercel 几分钟就好,Firebase 却一直失败? 两边所有权模型不同。Vercel 在 CNAME/A 记录可解析后就自动签证书;Firebase 必须先完成单独的 TXT 验证(域名在 Vercel 能用、Firebase 不行)。
  • 能用 Cloudflare 挡在 Firebase 前面吗? 能。证书签发期间把 Cloudflare DNS 记录设成 “DNS only”(灰云),签完再切 “Proxied”(橙云)。

相关阅读

标签: #独立开发 #Firebase #部署 / 托管 #域名 #DNS #SSL