Search code examples
node.jsreactjsfirebase-authenticationnext.jsfirebaseui

Protected Route With Firebase


I used Firebase for User Auth in my Next.js Application. I want to protect a user on the client-side. I used firebase firebaseui react-firebaseUI to implement Google Auth. How to secure a Route in the Client-side itself

  const uiConfig = {
    signInFlow: "popup",
    signInSuccessUrl: "/dashboard",
    signInOptions: [firebase.auth.GoogleAuthProvider.PROVIDER_ID],
  }

I want to protect the dashboard Route. Thanks in advance :)


Solution

  • Router:

    At first you'll need to maintain a router which would contain all your public and protected routes.

    
    import React from 'react';
    
    import {
      Route,
      Switch,
      BrowserRouter,
    } from 'react-router-dom';
    
    import ProtectedRoute from './Protected';
    
    import Foo from './Foo';
    import Bar from './Bar';
    
    const Routes = () => (
      <BrowserRouter>
        <Switch>
          // public route
          <Route exact path="/foo" component={Foo} />
    
          // protected route
          <ProtectedRoute exact path="/bar" component={Bar} />
    
          // if user hits a URL apart from the above ones, render a 404 component
          <Route path="*" component={NotFound} />
        </Switch>
      </BrowserRouter>
    );
    
    export default Routes;
    
    

    Protected Route:

    This is the protect route which would handle if a user should be allowed to access a protect page on your app based on it's auth status.

    import React from 'react';
    
    import { useAuthStatus } from '../hooks';
    
    import Spinner from '../Spinner';
    import UnAuthorised from '../UnAuthorised';
    
    const ProtectedRoute = ({ component: Component }) => {
      // a custom hook to keep track of user's auth status
      const { loggedIn, checkingStatus } = useAuthStatus();
    
      return (
        <>
          {
            // display a spinner while auth status being checked
            checkingStatus
              ? <Spinner />
              : loggedIn
                // if user is logged in, grant the access to the route
                // note: in this example component is Bar
                ? <Component />
                // else render an unauthorised component
                // stating the reason why it cannot access the route
                : <UnAuthorised />
          }
        </>
      );
    };
    
    export default ProtectedRoute;
    

    Firebase Auth Status:

    Well, this is the custom hook to keep track of user logging in and logging out.

    
    import { useEffect, useState } from 'react';
    
    import { firebase } from '../config';
    
    export const useAuthListener = (): void => {
      // assume user to be logged out
      const [loggedIn, setLoggedIn] = useState(false);
    
      // keep track to display a spinner while auth status is being checked
      const [checkingStatus, setCheckingStatus] = useState(true);
    
      useEffect(() => {
        // auth listener to keep track of user signing in and out
        firebase.auth().onAuthStateChanged((user) => {
          if (user) {
            setLoggedIn(true);
          }
    
          setCheckingStatus(false);
        });
      }, []);
    
      return { loggedIn, checkingStatus };
    };