Authenticate in React with Firebase Auth
Tags: react, firebase, authentication
Published: 2022-01-11 04:57:57

Authentication is something almost every modern web app needs. I've user Auth0 and Next Auth but Firebase seems to provide the easiest way to get authentication up and running.

## Registering a Firebase App

Now we need to create a new project in firebase. Navigate to [Firebase Console](https://console.firebase.google.com) and click `Add project`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcvmdont68dia5oytxta.png)

After creating this project and you are in the project console click on the Web icon to create a new web app. Follow the directions and copy the config which will look something like this.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jsdgf9ovbqrcbjguf3bf.png)
 

After creating this project navigate to the authentication tab and click `Get Started`. Then click `Google`


## Getting Started

```shell
npm install firebase
```

create a new folders in `/src` named `/lib/auth`. Inside this auth folder create a file `index.js`

first lets import what we need and initialize our constants
```jsx
import {getAuth, GoogleAuthProvider, signInWithPopup, onAuthStateChanged} from 'firebase/auth'
import {initializeApp} from 'firebase/app'
import { createContext, useContext, useEffect, useState } from 'react'


const app = initializeApp({
    apiKey: process.env.REACT_APP_apiKey,
    authDomain: process.env.REACT_APP_authDomain,
    projectId: process.env.REACT_APP_projectId,
    storageBucket: process.env.REACT_APP_storageBucket,
    messagingSenderId: process.env.REACT_APP_messagingSenderId,
    appId: process.env.REACT_APP_appId
})


const auth = getAuth()

const googleProvider = new GoogleAuthProvider()

const UserContext = createContext()
```

We need to create a [context](https://reactjs.org/docs/context.html) provider so that we can access the user object in all components

####`/src/lib/auth/index.js`
```jsx
export const AuthProvider = ({children}) => {

    const [user, setUser] = useState()

    useEffect(() => {
        onAuthStateChanged(auth, (user) => {
            if(user) {
                setUser(user)
            } else {
                setUser(undefined)
            }
        })
    }, [])
    
    return (
        <UserContext.Provider value={user}>
            {children}
        </UserContext.Provider>
    )
}

export const googleSignIn = () => {
    signInWithPopup(auth, googleProvider)
}
```
`onAuthStateChanged` creates an observer for changes to the user's sign-in state.

Now lets wrap out base level components with this `AuthProvider`
####`index.js`
```jsx
ReactDOM.render(
  <React.StrictMode>
    <AuthProvider>

      <App />
    
    </AuthProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

Finally lets create a `signInGoogle`, a `signOut` and a `useAuth` function
```jsx
export const useAuth = () => {
    return useContext(UserContext)
}

export const googleSignIn = () => {
    signInWithPopup(auth, googleProvider)
        .then(value => {})
        .catch(reason => {console.error(reason)})
}

export const signOut = () => {
    auth.signOut()
        .then(value => {})
        .catch(reason => {console.error(reason)})
}
```

now in our `App.js` we can use these functions
```jsx
import {googleSignIn, signOut, useAuth} from './lib/auth'

function App() {

  const user = useAuth()

  return (
    <div>
      {JSON.stringify(user)}
      <button onClick={(e) => {
        e.preventDefault()
        googleSignIn()
      }}>Sign in with google</button>
      <button onClick={(e) => {
        e.preventDefault()
        signOut()
      }}>Sign Out</button>
    </div>
  );
}

export default App;
```
Full code [`here`](https://github.com/dmuraco3/react-firebase-blog).