I'm trying to build a nextJS app with firebase (building a twitter-clone for training) and now I want to fetch() the tweets in my DB to render them on my page using getServerSideProps() function here is my code ->
Home.jsx components
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 [];
}
};
I can access the tweets returned from the getTweets() function in my VSCode console by using (console.log('tweets in getServerSideProps() :', tweets)
shows me the tweets in my database. It's an array of objects. However, I am unable to display them on the pages. It seems like the props are not being passed to the pages, despite my efforts to do so correctly.
I think the issue either comes from my use of getServerSideProps() or from my getTweets function that retrieves tweets from the database. However, I don't understand why I have access to them in my VSCode console if that's the case... it doesn't make sense.
By using useEffect in this way :
useEffect(() => {
async function fetchTweets() {
const res = await fetch("http://localhost:3000/api/getTweetAPI");
const data = await res.json();
setTweets(data);
}
fetchTweets();
}, []);
I can display the tweets on my page, but that's not what we expect from a NextJS project. I would like to use getServerSideProps(). Should I not retrieve the tweets this way? However, this method works, so I don't think the issue comes from the getTweets function. In this way, it is used in the api/getTweetAPI.js folder. This file uses getTweets(), and then I use fetch() to retrieve the data from this API.
Thanks for reading me!
I am trying to display a list of tweets from my Firebase database. The useEffect() method works by fetching the data on the client-side, but it doesn't work on the server-side with getServerSideProps(), despite several attempts. I even asked for help from GPT-4 and the AI cannot helped me...