DEV Community

Cover image for Authenticating Users In Firebase and managing Auth state using react-query-firebase
Dennis kinuthia
Dennis kinuthia

Posted on

3 2

Authenticating Users In Firebase and managing Auth state using react-query-firebase

this is part 2 to the set up process here

This tutorial's course files on the initial commit + adding auth course files

First step is to set up react-router-dom routes,

import React from 'react';
import './App.css';
import { Routes, Route } from "react-router-dom";
import { BrowserRouter } from 'react-router-dom';
import { Toolbar } from './components/Toolbar/Toolbar';
import { Project } from './components/Projects/Project';
import { Home } from './components/Home/Home';

function App() {
  return (
    <div className="h-screen w-screen overflow-x-hidden ">
      <BrowserRouter>
      <div className="fixed top-[0px] right-1 w-full z-30">
      <Toolbar />
      </div>
      <div className="w-full h-full mt-16 ">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/project" element={<Project />} />
         </Routes>
      </div>
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

adding two routes , home.tsx and projects.tsx . notice toolbar.txt doesn't need a route since it'll be available evey where making iy a good place to place the user profile pic


import React from 'react'
import { GrHome } from "react-icons/gr";
import { IconContext } from "react-icons/lib";
import { Link} from "react-router-dom";
import { FaUserCircle } from 'react-icons/fa';
import { useAuthSignOut} from '@react-query-firebase/auth';
import { auth } from '../../firebase/firebaseConfig';
import { User } from 'firebase/auth';
interface ToolbarProps {
user?:User|null
}

export const Toolbar: React.FC<ToolbarProps> = ({user}) => {
const mutation = useAuthSignOut(auth);
const userImg =user?.photoURL;
const image =userImg?userImg:'https://picsum.photos/id/237/100/100'
return (
 <div className='w-full bg-slate-500 h-16'>
<IconContext.Provider value={{ size: "25px", className: "table-edit-icons" }} >
 <div className='flex flex-grow flex-3'>
<div className='m-1 w-full p-3 bg-slate-800'>
     <Link to="/"><GrHome /></Link>
     </div>
     <div className='m-1 w-full p-3 bg-slate-600'>
     <Link to="/project">Project</Link>
     </div>
     <div className='m-1 w-fit p-3 bg-slate-700'>
      {!user?<FaUserCircle />
       :<img  
    //   @ts-ignore 
       src={image} 
       alt={'no'}
       onClick={()=>{mutation.mutate()}}
       className="rounded-[50%] h-full  w-[70px]"
       />}
     </div>

</div>   
</IconContext.Provider>
 </div>
);
}

Enter fullscreen mode Exit fullscreen mode

since this app will need to know who is who to display relevant data , we'll need to auth guard the routes to only show when authed else redirect to a login page

import { Navigate } from 'react-router-dom';

//@ts-ignore
export const ProtectedRoute = ({ user, children }) => {
    if (!user) {
      return <Navigate to="/login" replace />;
    }

    return children;
  };
Enter fullscreen mode Exit fullscreen mode

so we'll wrap our routes with the above component

import React from "react";
import "./App.css";
import { Routes, Route} from "react-router-dom";
import { BrowserRouter} from "react-router-dom";
import { Toolbar } from "./components/Toolbar/Toolbar";
import { Project } from "./components/Projects/Project";
import { Home } from "./components/Home/Home";
import { useAuthUser } from "@react-query-firebase/auth";
import { auth } from "./firebase/firebaseConfig";
import { Login } from "./components/auth/Login";
import { ProtectedRoute } from "./components/auth/PrivateRoutes";

function App() {
const user= {}
 return (
    <div className="h-screen w-screen overflow-x-hidden ">
      <BrowserRouter>
        <div className="fixed top-[0px] right-1 w-full z-30">
          <Toolbar user={user} />
        </div>
        <div className="w-full h-full mt-16 ">
          <Routes>
            <Route
              path="/"
              element={
                <ProtectedRoute user={user}>
                  <Home />
                </ProtectedRoute>
              }
            />

            <Route
              path="/project"
              element={
                <ProtectedRoute user={user}>
                  <Project />
                </ProtectedRoute>
              }
            />
            {/* @ts-ignore */}
            <Route path="/login" element={<Login user={user} />} />
          </Routes>
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

we also added a login route .

setting up the authentication part is pretty straight forward itself , in your firebaseConfig.ts file export the auth from getAuth()

import { initializeApp } from "firebase/app";
import { getAuth} from "firebase/auth";


const firebaseConfig = {
//your firebase app credentials go here
  };

const app = initializeApp(firebaseConfig);

export const provider = new GoogleAuthProvider();
export const auth = getAuth(app)
Enter fullscreen mode Exit fullscreen mode

and using the react-query-firebase hooks we can query the auth state with ust one line

  const query = useAuthUser("user", auth);
  const user = query.data;
  if (query.isFetching) {
return <div className="w-full h-full flex-center ">Loading...</div>;
  }

Enter fullscreen mode Exit fullscreen mode

and pass in the user object into any child components that need it in app.tsx

as for adding user i chose google signinwithRedirect

import { GoogleAuthProvider, signInWithRedirect } from "firebase/auth";
import { auth} from "../../firebase/firebaseConfig";

const provider = new GoogleAuthProvider();
provider.addScope('https://mail.google.com/');
export const loginUser= () => {
signInWithRedirect(auth, provider)
.then((result:any) => {
console.log("sign in successful result  === ",result)
// The signed-in user info.
    const user = result.user;
  }).catch((error) => {
// Handle Errors here.
console.log("sign in error  === ",error)

 });



}
Enter fullscreen mode Exit fullscreen mode

in the repo you'll also notice that you can log out on profile pic click

using the hook
const mutation = useAuthSignOut(auth);

then calling
mutation.mutate();

on profile pic clicked

and thats it for authentication in te next part we'll begin the functionalty part with firestore

references:
react-query-firebase auth
firebase auth using google
setting up firebase emulator for testing

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs