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

NextJS中getServerSideProps传递Props渲染Firebase推文失败

问题:getServerSideProps传递推文Props失败,页面无法渲染

我正在用NextJS结合Firebase开发推特克隆训练项目,尝试通过getServerSideProps函数从Firebase数据库获取推文并传递给Home页面组件。控制台能打印出正确的推文数组,但页面无法渲染这些推文;而使用useEffect进行客户端fetch API请求的方式却能正常显示推文。需要排查getServerSideProps传递Props失败的问题。

相关代码

Home.jsx组件

import { useContext, useEffect} from 'react';
import { getTweets } from '@/firebase/getTweets';
import { useRouter } from 'next/router';
import { AuthContext } from '@/contexts/AuthContext';
import Image from 'next/image';
import Sidebar from "@/components/Sidebar"
import TweetForm from '@/components/TweetForm';
import Searchbar from '@/components/Searchbar';
import Tweet from '@/components/Tweet';
import logo from "/public/logo.png";
import Recommendation from '@/components/Recommendation';

export default function Home({ tweets }) {

  const { currentUser } = useContext(AuthContext);
  const router = useRouter();

  useEffect(() => {
    if(!currentUser) {
      router.push('/');
    }
  },[currentUser,router]);

  return (
    <div className="flex border-black h-screen xs:flex-col-reverse sm:flex-row md:w-[80%] lg:w-[80%] md:mx-auto lg:mx-auto">
        <Sidebar/>
        <div className="p-3 xs:h-[90%] xs:relative xs:overflow-auto xs:w-full sm:h-full xl:w-[40%] 2xl:w-[60%]">
          <TweetForm currentUser={currentUser}/>
          <div >
            {
              tweets && tweets.map((tweet) => 
                  (
                  <Tweet 
                    key={tweet.id}
                    username={tweet.username}
                    tweetContent={tweet.content}
                    profile={tweet.profileImage}
                  />
                )
              )
            }
          </div>
        </div>
        <div className="border w-[35%] xs:hidden sm:hidden lg:hidden xl:block">
          <div className="searchbar">
            <Searchbar/>
            <div className="p-4 w-[90%] mx-auto rounded-lg bg-gray-300">
              <Recommendation/>
              <Recommendation/>
              <Recommendation/>
              <Recommendation/>
              <Recommendation/>
            </div>
          </div>
        </div>
        <div className="w-full sm:hidden">
          <Image src={logo} alt="Twitter logo" width={75} height={75} className='xs:mx-auto' />
        </div>
    </div>
  )
}

export async function getServerSideProps() {
  const tweets = await getTweets();

  console.log('tweets in getServerSideProps() :', tweets)

  return {
    props: {
      tweets,
    }
  }
}

getTweets.js

import { collection, getDocs, orderBy, query } from "firebase/firestore";
import { db } from "./config";

export const getTweets = async () => {
  try {
    const tweetsRef = collection(db, "tweets");
    const q = query(tweetsRef, orderBy("createdAt", "desc"));
    const querySnapshot = await getDocs(q);
    const tweets = querySnapshot.docs.map((doc) => {
      return { id: doc.id, ...doc.data() };
    });
    return tweets;
  } catch (error) {
    console.error("Error getting tweets:", error);
    return [];
  }
};

可正常工作的客户端请求方式

useEffect(() => {
  async function fetchTweets() {
    const res = await fetch("http://localhost:3000/api/getTweetAPI");
    const data = await res.json();
    setTweets(data);
  }

  fetchTweets();
}, []);

排查解决方案

1. 修复Firebase数据序列化问题

NextJS的getServerSideProps返回的Props必须是可JSON序列化的数据,而Firebase的doc.data()可能包含Timestamp这类无法直接序列化的对象。客户端API请求能正常工作,是因为API路由返回数据时自动将Timestamp转为了字符串,但getServerSideProps直接传递原始数据会导致序列化失败,最终组件无法收到正确的Props。

修改getTweets.js中的数据处理逻辑,将Timestamp转为可序列化的字符串:

export const getTweets = async () => {
  try {
    const tweetsRef = collection(db, "tweets");
    const q = query(tweetsRef, orderBy("createdAt", "desc"));
    const querySnapshot = await getDocs(q);
    const tweets = querySnapshot.docs.map((doc) => {
      const tweetData = doc.data();
      // 将Firebase Timestamp转为ISO字符串
      return {
        id: doc.id,
        ...tweetData,
        createdAt: tweetData.createdAt?.toISOString() || new Date().toISOString()
      };
    });
    return tweets;
  } catch (error) {
    console.error("Error getting tweets:", error);
    return [];
  }
};

2. 验证组件实际接收的Props

在Home组件内添加日志,确认是否真的收到了tweets数据:

export default function Home({ tweets }) {
  // 新增日志,查看组件实际接收的props
  console.log('tweets received in Home component:', tweets);

  const { currentUser } = useContext(AuthContext);
  const router = useRouter();

  // ... 其余代码不变
}

如果日志显示tweets为undefined或空数组,说明序列化问题未解决;如果显示正确数组但不渲染,检查Tweet组件的Props映射是否正确(比如确认tweet.content字段是否存在,有没有拼写错误)。

3. 确认Firebase服务端初始化正确性

客户端的Firebase配置在服务端环境中可能无法正常工作,需要确保db实例在服务端能正确初始化。如果你的Firebase配置仅针对客户端,需要为服务端单独配置Admin SDK,或者确保服务端能访问到正确的Firebase环境变量。

4. 确认路由模式兼容性

如果使用的是NextJS 13+的App Router,getServerSideProps仅在Pages Router下生效。确认你的Home.jsx位于pages目录下,而非app目录。

内容的提问来源于stack exchange,提问作者fares.dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:57:05