Next.js中如何正确存储Firestore文档引用作为字段?
Firestore存储文档引用时显示为Map的问题解决
我在开发一个简单博客,想要将发布的文章与登录用户关联起来。明明创建了文档引用并打算存储为引用类型字段,但Firestore数据库里却显示成了Map格式(如图所示):

我的尝试代码
前端提交代码(发送数据到API路由)
登录用户信息存在Context中,提交文章时我尝试把用户的文档引用一起发给API:
import {useAuth} from '../../context/AuthContext'; function Page() { const {user} = useAuth(); const onSubmit = async () => { const { title, body } = content; await axios.post('/api/post', { title, slug: dashify(title), body, author: doc(db, 'users/' + user.uid) }); setContent({title: '', body: ''}); } }
API路由处理代码(创建文章)
const handler = async (req, res) => { try { const posts = await getDocs(postsRef); const postsData = posts.docs.map((post) => post.data()); if (postsData.some((post) => post.slug == "slug")) res.status(406).end(); else { const newPost = await addDoc(collection(db, 'posts'), { ...req.body, createdAt: serverTimestamp(), }); console.log(newPost, "post details"); res.status(200).json({ newPost }); } } catch (e) { console.log(e, "error occured post"); res.status(400).end(); } }; export default handler;
问题原因及解决方法
核心问题是:Firestore的DocumentReference对象无法通过HTTP请求直接序列化传递,前端发送的引用对象会被转换成普通JSON对象(也就是你看到的Map),到API路由后已经不是合法的引用类型了。
解决步骤如下:
- 前端仅传递用户UID,不要直接传
doc()创建的引用对象:
// 修改后的前端提交代码 const onSubmit = async () => { const { title, body } = content; await axios.post('/api/post', { title, slug: dashify(title), body, authorUid: user.uid // 只传递用户UID }); setContent({title: '', body: ''}); }
- 在API路由内创建文档引用,这样存入Firestore的就是合法的引用类型:
// 修改后的API路由代码 const handler = async (req, res) => { try { const posts = await getDocs(postsRef); const postsData = posts.docs.map((post) => post.data()); // 修正slug判断逻辑,匹配当前提交的slug if (postsData.some((post) => post.slug === req.body.slug)) { return res.status(406).end(); } // 在API侧创建用户文档引用 const authorRef = doc(db, 'users', req.body.authorUid); const newPost = await addDoc(collection(db, 'posts'), { title: req.body.title, slug: req.body.slug, body: req.body.body, author: authorRef, // 存入合法的文档引用 createdAt: serverTimestamp(), }); console.log(newPost, "post details"); res.status(200).json({ newPost }); } catch (e) { console.log(e, "error occured post"); res.status(400).end(); } }; export default handler;
另外补充原代码里的两处小问题:
- 前端代码里
page function()应为function Page()才符合React组件规范 - API路由中判断slug的逻辑有误,原代码固定匹配字符串
"slug",应改为匹配req.body.slug
内容的提问来源于stack exchange,提问作者naeemnh
相关产品推荐
相关产品推荐

