You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+Firebase部署Vercel时getStaticProps/Paths构建失败

问题描述

在Vercel部署Next.js站点,后端使用Firebase,动态路由通过getStaticProps、getStaticPaths拉取数据渲染。
本地构建始终成功,Vercel平台构建直接失败,构建过程仅输出警告无明确报错,已尝试将staticPageGenerationTimeout参数调高至2000秒仍未解决,最小复现代码如下:

export const getStaticPaths: GetStaticPaths = async () => {
  try {
    const builderCollection = collection(db, 'something')
    const builderSnapshot = await getDocs(builderCollection)
    const refs = []
    builderSnapshot.forEach((doc) => {
      const data = doc.data()
      if (data && data.ref) {
        console.log('Store: Firebase path data', data.ref)
        refs.push(data.ref)
      }
    })
    const paths = refs.map((ref: string) => {
      return {
        params: {
          ref,
        },
      }
    })
    return { paths, fallback: 'blocking' }
  } catch (error) {
    console.log(error)
    return { paths: [], fallback: 'blocking' }
  }
}

export const getStaticProps: GetStaticProps = async (context) => {
  try {
    const { ref } = context.params
    console.log('Store Ref:', ref)

    const builderCollection = collection(db, 'builder')
    const checkQuery = query(builderCollection, where('ref', '==', ref))
    const checkerSnapshot = await getDocs(checkQuery)
    let fbData: DocumentData | null = null
    let id: string
    checkerSnapshot.forEach((doc) => {
      if (doc.exists()) {
        id = doc.id
        fbData = doc.data()
      }
    })
    return {
      props: { data: fbData, id },
      revalidate: 1,
    }
  } catch (error) {
    console.log(error)
    return { props: { data: null } }
  }
}

排查与修复方案

按优先级从高到低逐一验证:

  • 修复代码隐式运行时错误
    现有getStaticProps存在变量未定义的致命问题:如果Firebase查询没有匹配到对应ref的文档,id变量不会被赋值,最终返回props时会直接抛出ReferenceError: id is not defined导致构建中断。本地测试时通常只验证有数据的路径,不会触发该问题,Vercel构建时只要有一个路径匹配不到数据就会构建失败。
    修正代码参考:
    export const getStaticProps: GetStaticProps = async (context) => {
      try {
        const { ref } = context.params as { ref: string }
        const builderCollection = collection(db, 'builder')
        const checkQuery = query(builderCollection, where('ref', '==', ref))
        const checkerSnapshot = await getDocs(checkQuery)
        let fbData: DocumentData | null = null
        let id: string | null = null // 提前初始化变量
        checkerSnapshot.forEach((doc) => {
          if (doc.exists()) {
            id = doc.id
            fbData = doc.data()
          }
        })
        // 无匹配数据直接返回404,不要返回结构残缺的props
        if (!fbData || !id) return { notFound: true, revalidate: 1 }
        return {
          props: { data: fbData, id },
          revalidate: 1,
        }
      } catch (error) {
        console.log('Page generate error:', error)
        return { notFound: true, revalidate: 1 }
      }
    }
    
  • 核对Vercel环境变量配置
    本地构建成功通常是因为本地.env.local配置了完整的Firebase初始化参数,若Vercel项目后台没有把Firebase所需的配置项(apiKey、projectId等)完整配置到环境变量中,且未覆盖生产/预览/开发三个环境,构建阶段Firebase初始化失败、拉取不到数据自然会构建失败。Vercel不会读取未提交到仓库的本地.env.local文件。
  • 降低构建阶段预渲染压力
    如果something集合文档量较大,getStaticPaths返回成百上千个路径时,Vercel构建阶段会逐个渲染每个页面,哪怕单页超时调到2000秒,总构建时长触达免费版45分钟上限依然会失败。既然已经配置了fallback: 'blocking',完全不需要在构建阶段预渲染所有页面,直接返回空路径数组即可:
    return { paths: [], fallback: 'blocking' }
    
    所有页面会在用户首次访问时实时生成,不影响访问体验,构建时间可以压缩到数秒。
  • 检查Firebase权限规则
    确认Firebase安全规则没有限制仅登录用户可读取集合数据——构建阶段没有用户登录态,请求会被Firebase直接拒绝导致拉数失败。同时确认配置给Vercel的Firebase凭证拥有something、builder两个集合的读权限。

内容的提问来源于stack exchange,提问作者dinesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:12:13