Next.js 13 App目录下Firebase Firestore数据缓存方案
解决方案:缓存Firebase获取的用户数据(60秒有效期)
针对你的场景,Next.js提供了两种可靠的方式来缓存自定义数据获取逻辑的结果,无需依赖API接口:
方法一:用unstable_cache包装数据获取函数
这个API可以直接缓存getUserDetailsByUsername函数的返回结果,按用户名作为缓存键,有效期60秒。
修改你的数据获取函数:
import { unstable_cache } from 'next/cache' // 包装原函数,指定缓存策略 export const getUserDetailsByUsername = unstable_cache( async (username: string): Promise<{ userDetails: any; message?: string }> => { const q = DB.collection('users').where('username', '==', username) const querySnapshot = await q.get() if (querySnapshot.empty) { return { userDetails: null, message: 'User not found' } } const userDetails = querySnapshot.docs[0].data() return { userDetails } }, // 缓存键的组成部分,确保不同用户名的缓存独立 (username) => ['user-details', username], { // 缓存有效期60秒 revalidate: 60, // 标记缓存分组,方便后续主动刷新 tags: ['user-data'] } )
相同用户名的请求会在60秒内复用缓存结果,不会重复调用Firebase。
方法二:页面级缓存(适合整个页面数据都需要缓存的场景)
在你的page.tsx中添加revalidate导出,指定页面数据的缓存有效期为60秒:
修改页面组件代码:
// sections import { Metadata } from 'next' import { getUserDetailsByUsername } from 'src/queries/user' import { ProfileView } from 'src/sections/username/view' // ---------------------------------------------------------------------- type Props = { params: { username: string } } // 设置页面数据缓存有效期为60秒 export const revalidate = 60 export async function generateMetadata({ params }: Props): Promise<Metadata> { return { title: `${decodeURIComponent(params?.username)} | Prozo`, } } export default async function ProfilePage({ params }: { params: { username: string } }) { const { userDetails } = await getUserDetailsByUsername(params?.username?.slice(3)) return <ProfileView userDetails={userDetails} /> }
这种方式会缓存整个页面的服务端渲染结果,包括getUserDetailsByUsername的调用结果,60秒内相同用户名的请求会直接返回缓存的页面。
补充说明
- 函数级缓存(
unstable_cache)粒度更细,适合只需要缓存特定数据逻辑的场景;页面级缓存是整体缓存,适合整个页面内容无需频繁更新的情况。 - 若需要主动刷新缓存(比如用户更新了个人资料),可以使用
revalidateTag或revalidatePathAPI手动清除对应缓存。
内容的提问来源于stack exchange,提问作者Desai Hardik
相关产品推荐
相关产品推荐

