0

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...

fares.dev
  • 1
  • 1
  • is Home.jsx under the component folder or the page folder? – Peter Haddad Apr 19 '23 at 17:53
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Apr 19 '23 at 17:57
  • Home.jsx is in the page folder, it's a page not a component that's why i'm using getServerSideProps() inside – fares.dev Apr 19 '23 at 18:04
  • When try to console.log the props tweets (the one returned from getServerSideProps()) inside my pages it just show "undefined" – fares.dev Apr 19 '23 at 18:38
  • which nextjs version are u using? Is getServersideprops working in other pages? – Peter Haddad Apr 19 '23 at 18:57
  • okay the problems is solved it was from the destructuration of the props returned by "getStaticProps()" here -> I should have do it this way function Home({ pageProps }) { const {tweets} = pageProps; } it's because there is pageProps between the tweets props and props – fares.dev Apr 19 '23 at 19:39

0 Answers0