next-firebase-auth 项目使用示例详解
next-firebase-auth 是一个用于 Next.js 和 Firebase 认证集成的库,它简化了在 Next.js 应用中实现 Firebase 认证的流程。本文将详细介绍该库的各种使用场景和最佳实践。
在 Vercel 中添加 Firebase 认证凭据
将 Firebase 认证凭据作为环境变量添加到 Vercel 有多种方法:
通过 Vercel 控制台添加
- 在 Vercel 控制台的环境变量设置中,将认证凭据用双引号包裹后添加
- 在 next-firebase-auth 配置中使用该环境变量:
authCredentials: process.env.FIREBASE_AUTH_CREDENTIALS
通过 Vercel CLI 添加
- 使用 CLI 添加带双引号的认证凭据:
vercel secrets add firebase-auth-credentials '"my-key-here"'
- 在配置中使用 JSON.parse 解析:
authCredentials: process.env.FIREBASE_AUTH_CREDENTIALS
? JSON.parse(process.env.FIREBASE_AUTH_CREDENTIALS)
: undefined
其他格式处理方案
对于认证凭据中的换行符转义问题,可以采用字符串替换等方法处理。开发者社区中有多种讨论方案可供参考。
使用 Firebase 应用
next-firebase-auth 会自动初始化默认的 Firebase admin 应用和 Firebase JS SDK 应用(如果尚未初始化)。你也可以选择在初始化 next-firebase-auth 之前自行初始化 Firebase。
前端组件中使用示例
import { getApp } from 'firebase/app'
import { getFirestore, collection, onSnapshot } from 'firebase/firestore'
import { useEffect } from 'react'
const Artists = () => {
const [artists, setArtists] = useState(artists)
useEffect(() => {
return onSnapshot(collection(getFirestore(getApp()), 'artists'), (snap) => {
if (!snap) return
setArtists(snap.docs.map((doc) => ({ ...doc.data(), key: doc.id })))
})
}, [])
return (
<div>
{artists.map((artist) => (
<div>{artist.name}</div>
))}
</div>
)
}
后端管理应用中使用示例
import { getAuth } from 'firebase-admin/auth'
import { init } from 'next-firebase-auth'
// 确保为API路由初始化NFA
init({
// ... 配置
})
const myCode = () => {
const auth = getAuth()
// ...
}
用户认证信息获取
在 API 路由中获取用户
可以使用 verifyIdToken 或 getUserFromCookies 方法轻松获取 API 路由中的用户信息。
在独立后端环境中获取用户
如果你的应用需要在独立的后端环境(如API服务)中认证用户:
- 安装依赖:next-firebase-auth 和 firebase-admin
- 确保环境支持 fetch(必要时添加 polyfill)
- 像平常一样初始化 next-firebase-auth
- 确保 Firebase admin 和 cookie 设置与 Next.js 应用中的完全一致
- 使用 verifyIdToken 或 getUserFromCookies 方法
示例代码:
import { init, getUserFromCookies } from 'next-firebase-auth'
import './fetch-polyfill'
init({
// ... 配置
})
const myApiHandler = ({ req }) => {
const user = await getUserFromCookies({
req,
includeToken: true,
})
// ... 其他逻辑
return {
// 返回数据
}
}
动态重定向
next-firebase-auth 支持根据用户登录状态动态重定向到登录页或应用页,目标URL可以是运行时确定的动态URL。
示例配置:
import { init } from 'next-firebase-auth'
import absoluteUrl from 'next-absolute-url'
const initAuth = () => init({
authPageURL: ({ ctx }) => {
const isServerSide = typeof window === 'undefined'
const origin = isServerSide
? absoluteUrl(ctx.req).origin
: window.location.origin
const destPath =
typeof window === 'undefined' ? ctx.resolvedUrl : window.location.href
const destURL = new URL(destPath, origin)
return `auth-ssr?destination=${encodeURIComponent(destURL)}`
},
appPageURL: ({ ctx }) => {
// 类似逻辑处理应用页重定向
// 包含安全验证逻辑
return destURL
},
// ... 其他配置
})
测试与模拟(Jest)
测试使用 next-firebase-auth 的组件时,可以使用 Jest 的手动模拟功能。
基本模拟设置
- 在项目根目录创建
__mocks__/next-firebase-auth/index.js
- 定义模拟行为:
const { AuthAction } = require('next-firebase-auth')
const NFAMock = jest.createMockFromModule('next-firebase-auth')
module.exports = {
...NFAMock,
init: jest.fn(),
withUser: jest.fn(() => (wrappedComponent) => wrappedComponent),
useUser: jest.fn(() => ({
// 返回默认用户数据
})),
AuthAction,
}
用户模拟工具
创建用户模拟生成器:
const mockFirebaseUser = {
displayName: '测试用户',
// ... 其他字段
}
const getMockUser = (isLoggedIn = true) => ({
id: isLoggedIn ? 'test123' : null,
email: isLoggedIn ? 'test@example.com' : null,
emailVerified: isLoggedIn,
getIdToken: jest.fn(async () => (isLoggedIn ? 'test_token' : null)),
clientInitialized: isLoggedIn,
firebaseUser: isLoggedIn ? mockFirebaseUser : null,
signOut: jest.fn(),
serialize: jest.fn(() => 'serialized_auth_user'),
})
组件测试示例
import { render, screen } from '@testing-library/react'
import { useUser, withUser } from 'next-firebase-auth'
import getMockUser from '../../utils/test-utils/get-mock-auth-user'
jest.mock('next-firebase-auth')
describe('UserDisplayName', () => {
let UserDisplayName
beforeEach(() => {
useUser.mockReturnValue(getMockUser())
withUser.mockImplementation(() => (wrappedComponent) => wrappedComponent))
UserDisplayName = require('./').default
})
it('显示登录用户的名称', () => {
render(<UserDisplayName />)
expect(screen.getByText(getMockUser().firebaseUser.displayName)).toBeInTheDocument()
})
it('未登录时显示"anonymous"', () => {
useUser.mockReturnValue(getMockUser(false))
render(<Header />)
expect(screen.getByText('anonymous')).toBeInTheDocument()
})
})
TypeScript 测试注意事项
在 TypeScript 测试中,需要类型断言来访问 mock 方法:
(useUser as jest.Mock).mockReturnValue(getMockUser())
(withUser as jest.Mock).mockImplementation(() => (wrappedComponent: ComponentType) => wrappedComponent)
通过以上示例和说明,开发者可以全面了解 next-firebase-auth 在不同场景下的使用方法,从而在自己的 Next.js 项目中实现完善的 Firebase 认证功能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考