你把域名指向 Vercel,一切顺利。同一个域名换到 Firebase Hosting,却卡在 Needs setup / Pending,或者验证过了但 SSL 证书一直发不出来。
最快修法: 先从 Vercel 移除该域名,再到 Firebase 控制台用 Add custom domain,把它给的记录原样抄过去——先抄验证用的 TXT 记录,验证通过后再抄它给的 A 和 AAAA 记录。把 apex 上所有 Vercel 时代留下的 A、AAAA、CNAME 记录全删掉;如果你用 Cloudflare,把这些记录设为 DNS only(灰云),直到证书签发完成。然后耐心等——签发最多可能要 24 小时,通常一小时内搞定。
为什么这事容易让人意外:Vercel 把大部分 DNS 工作抽象掉了,对残留记录也很宽容。Firebase 很严格,像 AWS——给你精确的值,只要有冲突就拒绝签发证书。截至 2026 年 6 月,Firebase Hosting 还要求你删掉残留的 AAAA 记录,不只是 A/CNAME——这正是”看起来照 Vercel 那套都对了却还是失败”的头号原因。
先判断你属于哪一类
| 控制台里的现象 | 最可能的原因 | 跳到 |
|---|---|---|
一直 Needs setup,点 Verify 总失败 | TXT 记录没加、写错或没传播 | 第 3 步 |
已验证但状态停在 Pending、没 SSL | Vercel 老 A/AAAA/CNAME 还在,或 CAA 挡了 CA | 第 4-5 步 |
A/AAAA 看着没错也是 Pending | Cloudflare 代理开着,或 CAA 漏了某个 CA | 第 5-6 步 |
| 域名显示被别处占用 | 同一域名加进了另一个 Firebase 项目 | 原因 6 |
| 全都对,过了 48 小时仍无证书 | Firebase 侧队列问题,开工单 | ”哪些情况不是你操作错了” |
常见原因
按命中率从高到低。
1. Vercel 老记录还在(包括 AAAA)
最经典的疏漏。你加了 Firebase 的 A 记录,却没删 apex 上指向 Vercel 的老记录,于是 DNS 仍然返回 Vercel 的 IP。Firebase 明确要求删掉所有指向其它服务商的 A、AAAA、CNAME 记录,只要它们还在,证书就发不出来。
怎么判断:
dig +short A yourdomain.com
dig +short AAAA yourdomain.com
输出里出现 Vercel 的 76.76.21.21(或来自旧主机的任何 IPv6)就是残留。Firebase 的 IP 现在是 Google 自家的(向导目前会显示类似 199.36.158.100 的值,但请永远以你控制台里那一对为准)。
2. A/AAAA 值填错——Firebase 会给你确切的值
Firebase 不接受任意 IP。Add custom domain 向导会给出针对你项目的具体 A 和 AAAA 记录。Vercel 的 76.76.21.21 永远不行;从旧博客抄来的 IP(早年 Fastly 那对 151.101.x.x)也早已过时——只用控制台显示的值。
怎么判断: Firebase Console → Hosting → 你的域名 → 记录面板列出确切的 A 和 AAAA 值。跟你线上 DNS 对一遍。
3. TXT 验证记录没加或没传播
Firebase 验证域名前要求 apex 上有一条 TXT 记录证明归属权。没加或还没传播,点 Verify 就失败。这条 TXT 要一直留着——Firebase 不只用它做首次签发,还用来授权后续的证书续期。
怎么判断:
dig +short TXT yourdomain.com
应能看到 Firebase 的验证字符串。什么都没返回,就是没加或还没传播。
4. CAA 记录挡了证书颁发机构
Firebase 用 Let’s Encrypt 和 Google Trust Services 两家签发证书。只要你有 CAA 记录,就必须同时允许这两家。只列了别家 CA(或只有 letsencrypt.org 没有 pki.goog)的 CAA 记录会悄悄挡住签发。
怎么判断:
dig +short CAA yourdomain.com
有 CAA 记录就必须同时包含 letsencrypt.org 和 pki.goog。完全没有 CAA 反而没问题——默认两家都允许。
5. Cloudflare 代理在首次验证时干扰
Cloudflare 橙云代理把你的真实记录藏在 Cloudflare 的 IP 后面,Firebase 的验证器和 CA 质询看不到该看的东西,验证或首次签发就失败。
怎么判断: Cloudflare → DNS → Firebase 设置期间 apex 记录若是橙云(代理),就改成 DNS only(灰云),等证书签好再说。
6. 同一域名被另一个 Firebase 项目占用
一个域名只能被一个 Firebase 项目持有。如果你(或同事)在别处加过它,新项目就抢不到。
怎么判断: 检查你其它 Firebase 项目的 Hosting 页,除了你真正要用的那个项目,在其余项目里把域名都移除。
最短修复路径
第 1 步:先从 Vercel 移除域名
Vercel 项目 → Settings → Domains → 移除 yourdomain.com。这会释放 Vercel 的主张,避免它反复重置记录。
第 2 步:在 Firebase 加域名
Firebase Console → Hosting → Add custom domain → 输入 yourdomain.com。
选对向导:
- Quick setup —— 适用于新域名,或不介意立刻切流量的域名。
- Advanced setup —— 适用于仍在别处对外服务的线上域名。它会在你切 DNS 之前先建立 SSL 证书和归属权,实现零停机迁移。生产中的域名选这个。
随后 Firebase 会给出一条 TXT 归属记录,验证通过后再给指向 Hosting 的 A 和 AAAA 记录。
第 3 步:加 TXT 记录并验证
在 DNS 提供商按 Firebase 给的原样把 TXT 加到 apex(host 填 @ 或留空)。TTL 设 300-600,让改动快点传播。
等几分钟,用 dig +short TXT yourdomain.com 确认已生效,再到控制台点 Verify。(若 Verify 报错,多半是还没传播或值写错了,先核对再重试。)
第 4 步:加 A 和 AAAA 记录,删掉老的
验证后 Firebase 会显示它的 A 和 AAAA 记录(通常是两个 A 值,外加 IPv6 的 AAAA)。把它们全部加到 apex,TTL 设 300。
然后把 apex 上指向 Vercel 或任何其它主机的残留 A、AAAA、CNAME 全删掉。这一步是硬性要求——残留记录会挡住证书。
第 5 步:查 CAA 记录
dig +short CAA yourdomain.com
有 CAA 记录就确保它同时允许 letsencrypt.org 和 pki.goog。完全没有 CAA 就保持现状——默认两家都允许。
第 6 步:把 Cloudflare 记录设为 DNS only
用 Cloudflare 的话,把 apex 的 A/AAAA 记录改成 DNS only(灰云)做设置。证书签发、站点能跑 HTTPS 之后,再开回代理。
第 7 步:等 SSL 签发——别反复折腾
Firebase 文档写”最多 24 小时”,多数域名一小时内完成。不要反复删了重加——那会重置签发队列,反而更慢。
第 8 步:确认修好了
curl -sI https://yourdomain.com | head -3
正常的话返回 HTTP/2 200,证书受信任(浏览器不报警告)。想查得更细,可用 Google Admin Toolbox Dig 核对证书签发方和 DNS 值,并执行:
curl -svo /dev/null https://yourdomain.com 2>&1 | grep -i "issuer\|subject"
签发方(issuer)应是 Let’s Encrypt 或 Google Trust Services,主题(subject)应与你的域名一致。
哪些情况不是你操作错了
如果记录已验证且都正确(A/AAAA 对、无冲突、CAA 允许该 CA、没开代理),过了 48 小时仍没证书,那就是 Firebase 侧的队列问题。带上项目 ID 和域名,通过 Firebase Support 开工单。等的时候别再反复重加域名。
容易误判的情况
陷阱在于以为”DNS 就是 DNS”,Vercel 那套能原样照搬。不能。每个平台都有自己要求的值和容忍度——Vercel 把 Firebase 强制要求的 AAAA/CAA 细节藏了起来。严格照 Firebase 向导走,别拿别家文档或旧教程里的 IP 来顶。
预防建议
- 切换服务商之前先解绑旧主机的记录和绑定,不要事后补。
- 迁移时把 apex 上四类记录都清干净:A、AAAA、CNAME,以及残留的 TXT。
- 线上域名用 Advanced setup 向导,让证书在切流量前就备好。
- 点 Verify 前用
dig +short确认 TXT、A、AAAA 都已传播。 - 证书签发前 Cloudflare 记录一直保持 “DNS only”。
- 从控制台抄 Firebase 的确切 IP——不要近似,也不要复用旧值。
FAQ
- 为什么 Vercel 不挑 IP,Firebase 却要特定 IP? Firebase 通过 Google CDN 上一组与你项目绑定的固定 anycast A/AAAA 地址路由流量,并按域名签发依赖这些确切记录的证书。Vercel 把这一层藏在平台后面,所以容忍度更高。
- 真的必须删 AAAA 记录吗? 必须。截至 2026 年 6 月,只要有任何 AAAA(IPv6)记录还指向别家服务商,即便 A 记录正确,Firebase 也会拒绝签发证书。这是”看着都对却发不出证书”的头号原因。
- 能保留 Cloudflare 代理吗? 设置期间不能。先用 “DNS only”(灰云),等证书生效后再开回橙云代理,这样就能让 Cloudflare 的 CDN/WAF 挡在前面。
- SSL 一般要多久? 按文档最多 24 小时,通常一小时内。记录正确却过了 48 小时还 pending,那是 Firebase 侧问题——联系支持,别再重加域名。
- 需要 CAA 记录吗? 不需要。没有 CAA 时,Firebase 的 CA 默认就被允许。只有当你本来就限制签发时才加,并且要同时包含
letsencrypt.org和pki.goog。