I was making an app using NextJS, TailwindCSS, Firebase and It is working 100% correctly on local host but on deploying on Vercel, I get the following error :
15:18 Error: React Hook "useRouter" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks 17:39 Error: React Hook "useDocumentOnce" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
I am not able to understand why I get this error when deploying my app to Vercel.Maybe it's something related to redirect link in google API console
Here's my [id].js file :
import TextEditor from "../../components/TextEditor";
import Button from "@material-tailwind/react/Button";
import Icon from "@material-tailwind/react/Icon";
import { useRouter } from "next/dist/client/router";
import { db } from "../../firebase";
import { useDocumentOnce } from "react-firebase-hooks/firestore";
import { getSession, signOut, useSession } from "next-auth/client";
import Login from "../../components/Login";
function Doc() {
const [session, loading] = useSession();
console.log(session);
if (!session) return <Login />;
const router = useRouter();
const { id } = router.query;
const [snapshot, loadingSnapshot] = useDocumentOnce(
db.collection("userDocs").doc(session.user.email).collection("docs").doc(id)
);
// Redirect if user tries to access a URL they do not have access to...
if (!loadingSnapshot && !snapshot?.data()?.fileName) {
// Filename will not be present if the user doesnt have access...
router.replace("/");
}
return (
<div>
<header className="flex justify-between items-center p-3 pb-1">
<span onClick={() => router.push("/")} className="cursor-pointer">
<Icon name="description" size="5xl" color="blue" />
</span>
<div className="flex-grow px-2">
<h2 className="text-lg text-left">{snapshot?.data()?.fileName}</h2>
<div className="flex items-center text-sm -ml-1 h-8 text-gray-600 space-x-1">
<p className="option">File</p>
<p className="option">Edit</p>
<p className="option">View</p>
<p className="option">Insert</p>
<p className="option">Format</p>
<p className="option">Tools</p>
</div>
</div>
<Button
color="lightBlue"
buttonType="filled"
size="regular"
className="hidden md:!inline-flex h-10"
rounded={false}
block={false}
iconOnly={false}
ripple="light"
>
<Icon name="people" size="md" /> SHARE
</Button>
<img
onClick={signOut}
className="cursor-pointer h-10 w-10 rounded-full ml-2"
src={session.user.image}
alt=""
/>
</header>
<TextEditor />
</div>
);
}
export default Doc;
export async function getServerSideProps(context) {
const session = await getSession(context);
return {
props: {
session,
},
};
}

nulltouseDocumentOnce()if thesessionis not defined. Then you can move all the hook calls aboveif (!session) return <Login />;.