Im using nextjs app router and im trying to pull data from database and access it in app via fetch
export default async function Home() {
try {
const userData = await fetch("http://localhost:3000/api/userData")
.then((response) => response.json())
.then((data) => console.log("DATA: " + JSON.stringify(data)));
} catch (error) {
console.error("ERROR: " + error);
}
return <div></div>;
}
Console.log with data is always empty and there is no errors
import { firestore } from "@/firebase/firebase";
import { collection, getDocs, onSnapshot, query, where } from "firebase/firestore";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
let sessionId = cookies().get("sessionId")?.value;
if (!sessionId) {
sessionId = "";
}
let userData = undefined;
const userDataQuery = query(collection(firestore, "users"), where("sessionId", "==", sessionId));
const userFirstDoc = await getDocs(userDataQuery);
userFirstDoc.forEach((doc) => {
userData = doc.data();
});
const unsubscribe = onSnapshot(userDataQuery, (userSnapshot) => {
userSnapshot.forEach((doc) => {
userData = doc.data();
});
});
console.log(userData); // Returns proper user data
return NextResponse.json({ userData });
}
console.log(userData)
displays expected value but this value doesn't seems to be available via fetch
NextResponse.json()
and Response.json()
don't work/api/UserData
i can see user data object just fineFirst things first, I would highly recommend to change your code inside the Home
page. This is not the indended way of doing API request inside React. Your typical request inside the home
page should look like this for example:
import React, { useState, useEffect } from 'react';
export default function Home() {
const [userData, setUserData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("http://localhost:3000/api/userData");
const data = await response.json();
setUserData(data.userData);
} catch (error) {
setError(error);
console.error("ERROR: " + error);
}
};
fetchData();
}, []);
if (!userData) {
return <div>Loading...</div>;
}
return (
<div>
<h1>User Data</h1>
<p>Name: {userData.name}</p>
<p>Email: {userData.email}</p>
</div>
);
}
What is happening inside the code?
useData
and error
states. This will be filled after the fetch call, with the appropiate response.useEffect
hook, which in this case will be only called once inside the Home component (then its mounted).async
fetchData function, which does the fetch call. But furthermore it sets the states.I think this should solve your problem. Remember this is an example pseudo code and not just copy paste, there might be some mistakes, especially if you are using next.js.