Background
I am building a web app with a Reactjs and Firebase backend / auth. I have setup and AuthContextProvider and using React Router to navigate.
Problem
None of the routes are resolving.
Code
// App.js
import React from "react";
import {
BrowserRouter as Router,
Route,
Link,
Redirect,
} from "react-router-dom";
import { AuthContextProvider, useAuthState } from "./firebase";
import Navigation from "./components/layout/Navigation";
import Landing from "./components/screens/Landing";
import SignUp from "./components/screens/SignUp";
import SignIn from "./components/screens/SignIn";
import ForgotPassword from "./components/screens/ForgotPassword";
import Home from "./components/screens/Home";
import Profile from "./components/screens/Profile";
import Account from "./components/screens/Account";
import Admin from "./components/screens/Admin";
import * as ROUTES from "./constants/routes";
const AuthenticatedRoute = ({ component: C, ...props }) => {
const { isAuthenticated } = useAuthState();
console.log(`AuthenticatedRoute: ${isAuthenticated}`);
return (
<Route
{...props}
render={(routeProps) =>
isAuthenticated ? <C {...routeProps} /> : <Redirect to="/login" />
}
/>
);
};
const UnauthenticatedRoute = ({ component: C, ...props }) => {
const { isAuthenticated } = useAuthState();
console.log(`UnauthenticatedRoute: ${isAuthenticated}`);
return (
<Route
{...props}
render={(routeProps) =>
!isAuthenticated ? <C {...routeProps} /> : <Redirect to="/home" />
}
/>
);
};
const App = () => (
<AuthContextProvider>
<Router>
<Navigation />
<UnauthenticatedRoute exact path={ROUTES.SIGN_UP} component={SignUp} />
<UnauthenticatedRoute exact path={ROUTES.SIGN_IN} component={SignIn} />
<UnauthenticatedRoute
exact
path={ROUTES.PASSWORD_RESET}
component={ForgotPassword}
/>
<UnauthenticatedRoute exact path={ROUTES.LANDING} component={Landing} />
<AuthenticatedRoute exact path={ROUTES.ACCOUNT} component={Account} />
<AuthenticatedRoute exact path={ROUTES.ADMIN} component={Admin} />
<AuthenticatedRoute exact path={ROUTES.PROFILE} component={Profile} />
<AuthenticatedRoute exact path={ROUTES.HOME} component={Home} />
</Router>
</AuthContextProvider>
);
export default App;
// firebase.js
import { getAuth, onAuthStateChanged } from "@firebase/auth";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { useState, useEffect, useContext, createContext } from "react";
const firebaseConfig = {
...
};
export const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore();
export const AuthContext = createContext();
export const AuthContextProvider = (props) => {
const [user, setUser] = useState();
const [error, setError] = useState();
useEffect(() => {
const unsubscribe = onAuthStateChanged(getAuth(), setUser, setError);
return () => unsubscribe();
}, []);
return <AuthContext.Provider value={{ user, error }} {...props} />;
};
export const useAuthState = () => {
const auth = useContext(AuthContext);
return { ...auth, isAuthenticated: auth.user != null };
};
// routes.js
export const LANDING = "/";
export const SIGN_UP = "/signup";
export const SIGN_IN = "/login";
export const HOME = "/home";
export const ACCOUNT = "/account";
export const ADMIN = "/admin";
export const PASSWORD_RESET = "/forgot-password";
export const PROFILE = "/profile";
// Navigation.js
import React from "react";
import { Link } from "react-router-dom";
import { getAuth, signOut } from "firebase/auth";
import { useAuthState } from "../../firebase";
import * as ROUTES from "../../constants/routes";
import Navbar from "react-bootstrap/Navbar";
import Container from "react-bootstrap/Container";
import Nav from "react-bootstrap/Nav";
import NavDropdown from "react-bootstrap/NavDropdown";
const Navigation = () => {
const { user } = useAuthState();
return (
<div className="navigation">
<Navbar bg="light" expand="lg">
<Container>
<Link to={ROUTES.HOME}>
<Navbar.Brand>Underground</Navbar.Brand>
</Link>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
{user ? (
<NavDropdown title={user?.email} id="basic-nav-dropdown">
<Link to={ROUTES.ACCOUNT}>
<NavDropdown.Item>Account</NavDropdown.Item>
</Link>
<NavDropdown.Divider />
<NavDropdown.Item onClick={() => signOut(getAuth())}>
Logout
</NavDropdown.Item>
</NavDropdown>
) : (
<NavDropdown title="Users" id="basic-nav-dropdown">
<Link to={ROUTES.SIGN_IN}>
<NavDropdown.Item>Sign in</NavDropdown.Item>
</Link>
<Link to={ROUTES.SIGN_UP}>
<NavDropdown.Item>Signup</NavDropdown.Item>
</Link>
</NavDropdown>
)}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</div>
);
};
export default Navigation;
So why not resolving?
I don't think my router has anything configured wrong so why would the routes not resolve? They either resolve to /home for authenticated users, or /login for non-authenticated users, which suggests something to do with redirects?