集成 Next.js

使用 Firebase CLI,您可以将 Next.js Web 应用部署到 Firebase,并通过 Firebase Hosting 提供这些应用。CLI 会参照您的 Next.js 设置,并将其转换为 Firebase 设置,而您基本无需进行任何额外配置。如果您的应用包含动态服务器端逻辑,CLI 会将该逻辑部署到 Cloud Functions for Firebase。受支持的最新 Next.js 版本为 13.4.7。

准备工作

在开始将应用部署到 Firebase 之前,请先了解以下要求和相关选项:

  • 拥有 Firebase CLI 12.1.0 或更高版本。请务必使用您首选的方法安装 CLI
  • 可选:在 Firebase 项目中启用结算功能(如果您计划使用 SSR,则必须完成此操作)

  • 可选:使用实验性 ReactFire 库,以利用其适合在 Firebase 中使用的功能

初始化 Firebase

首先,请为您的框架项目初始化 Firebase。对于新项目,您可以使用 Firebase CLI 完成初始化;对于现有项目,则可以通过修改 firebase.json 执行此操作。

初始化新项目

  1. Firebase CLI 中,启用 Web 框架预览:
    firebase experiments:enable webframeworks
  2. 通过 CLI 运行初始化命令,然后按照提示操作:

    firebase init hosting

  3. 在看到“Do you want to use a web framework?(experimental)”后输入“yes”

  4. 选择您的托管用源目录。如果这是一个现有的 Next.js 应用,则 CLI 执行过程会自行完成,您可以继续执行下一部分的操作。

  5. 如果出现提示,请选择 Next.js。

提供静态内容

初始化 Firebase 后,您可以使用标准部署命令来提供静态内容:

firebase deploy

您可以通过实际网站查看您部署的应用

预呈现动态内容

Firebase CLI 将检测您的应用使用的是 getStaticProps 还是 getStaticPaths

可选:与 Firebase JS SDK 集成

如果将 Firebase JS SDK 方法同时添加到服务器软件包和客户端软件包,请在使用产品之前检查 isSupported(),以防范运行时错误。并非所有环境都支持全部产品

可选:与 Firebase Admin SDK 集成

如果将 Admin SDK 软件包添加到浏览器 build 中,这些软件包会执行失败;只能在 getStaticPropsgetStaticPaths 内引用这些软件包。

提供全动态内容 (SSR)

Firebase CLI 将检测您的应用是否使用了 getServerSideProps。在这种情况下,CLI 会将函数部署到 Cloud Functions for Firebase 以运行动态服务器代码。您可以在 Firebase 控制台中查看这些函数的相关信息,例如其网域和运行时配置。

使用 next.config.js 配置 Hosting 行为

图片优化

虽然系统支持使用 Next.js 图片优化,但会导致在 Cloud Functions for Firebase 中创建一个函数,即便您未使用 SSR。

重定向、重写和标头

Firebase CLI 会参照 next.config.js 中的重定向重写标头,并在部署时将它们转换为各自的等效 Firebase Hosting 配置。如果 Next.js 重定向、重写或标头无法转换为等效的 Firebase Hosting 标头,那么操作会回退并改为构建一个函数,即便您未使用图片优化或 SSR。

可选:与 Firebase Authentication 集成

Web 框架感知型 Firebase 部署工具可以使用 Cookie 自动同步客户端和服务器的状态。下面提供了一些在 SSR 中访问身份验证上下文的方法:

  • 可视需要在 Express res.locals 对象中添加经过身份验证的 Firebase 应用实例 (firebaseApp) 及当前登录的用户 (currentUser)。之后,便可以在 getServerSideProps 中访问这些信息。
  • 经过身份验证的 Firebase 应用的名称会在路由查询 (__firebaseAppName) 中提供。这样便可在身份验证上下文中实现手动集成:
// get the authenticated Firebase App
const firebaseApp = getApp(useRouter().query.__firebaseAppName);