React Router Dom 6 page redirected to sign in page even when user is signed in

I’m using firebase for user authentication and react-router-dom 6 for private routes. The "/account" page is protected and wrapped inside private routes. I have a Nav component, which has an icon that redirects to the "/account" page, the code is as follows:

export default function Nav() {
    const navigate = useNavigate();

    return (
         <nav className='navbar'>
            <div className="account-container">
                <RiUser3Fill className='account-icon menu-icon' onClick={()=>{navigate("account")}}/>
                <BsCartFill className='cart-icon menu-icon' onClick={()=>{navigate('cart')}}/>

When I click on the account icon and the user is logged in, the page would redirect to the protected account page. But the problem is, when I refresh the page at "/account", or type in the URL to get to "/account", the page would always be redirected to "/signin" page even when the user is already signed in. Below are my other components:


function App() {
  return <BrowserRouter>
      <Route path="/" element={<Nav/>}>
        <Route element={<PrivateRouter/>}>
          <Route path="/account" element={<Account/>}/>
          <Route path="/cart" element={<Cart/>}/>
        <Route path='/signup' element={<Signup/>}/>
        <Route path='/signin' element={<Signin/>}/>


export default function PrivateRouter() {
    const {currentUser} = useAuth();
    const location = useLocation();
    if(!currentUser) return <Navigate state={{from:location}} to="/signin"/>
    return <Outlet />


import React, {useContext, useEffect, useState} from 'react';
import { signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut, onAuthStateChanged,
passwo } from 'firebase/auth';
import { auth } from '../utility/firebase';

const AuthContext = React.createContext(); 

export function useAuth(){
    return useContext(AuthContext);

export default function AuthProvider({children}) {
    const [currentUser, setCurrentUser] = useState();

        const unsub = onAuthStateChanged(auth,user=>{
        return unsub;

    function signin(email,password){
        return signInWithEmailAndPassword(auth,email,password);

    function signup(email,password){
        return createUserWithEmailAndPassword(auth,email,password);

    function signout(){
        return signOut(auth);

const values = {

  return <AuthContext.Provider value={values}>

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

The currentUser initial value is undefined until updated by the auth check in the useEffect.

const [currentUser, setCurrentUser] = useState(); // <-- undefined

useEffect(() => {
  const unsub = onAuthStateChanged(auth, user => {
    setCurrentUser(user); // <-- sets user state after initial render

  return unsub;
}, []);

So when refreshing the page, i.e. remounting the app, the currentUser condition in the auth check is falsey and user is bounced to login/signin page.

If the currentUser is still undefined, i.e. the app hasn’t determined/confirmed either way a user’s authentication status, you should return null and not commit to redirecting or allowing access through to the routed component.

export default function PrivateRouter() {
  const { currentUser } = useAuth();
  const location = useLocation();

  if (currentUser === undefined) return null; // or loading spinner, etc...

  return currentUser
    ? <Outlet />
    : <Navigate to="/signin" replace state={{ from: location }} />;

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply