DEV Community

Haruka Kato
Haruka Kato

Posted on

Firebase Authentification using google sign-in OnAuthStateChanged logout

I was working on firebase authentification using google sign-in and a lot of articles online were explaining about Sign-in but there weren't many articles explaining logout.

It took me a while to figure this out so I want to share it here.

This is my directory structure.

So first, you sign in with google on this page.
Screen Shot 2021-01-27 at 10.30.04

Once you successfully signed in, the logout button will show up on the header. Screen Shot 2021-01-27 at 10.48.03

So, I wanted to show this logout button when a user is signed in. Here is my SignIn.js

import React, { useState } from 'react';
import 'firebase/auth'
import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import Header from './BasicComponents/Header';
import Footer from './BasicComponents/Footer';
import Button from '@material-ui/core/Button';
import { useFirebase } from "react-redux-firebase";
import { useDispatch, useSelector } from 'react-redux';
import { push } from 'connected-react-router'

const useStyles = makeStyles((theme) => ({
    root: {
        flexGrow: 1,
    },
    paper: {
        textAlign: 'center',
        backgroundColor: '#C0C0C0',
        opacity: 0.7,
        borderRadius: 50,
        height: 500,
        paddingTop: 20,
    },
    grid: {
        position: 'block',
        margin: '0 auto',
        marginTop: 50,
        marginBottom: 50,
    },
    input:{
        width: '70%',
        height: 50,
        fontSize: 15,
        padding: '.3em',
        borderRadius: 10,
        border: '1px solid #aaa',
    },
    input1:{
        width: '70%',
        height: 50,
        fontSize: 15,
        padding: '.1em',
        marginRight: 5,
        borderRadius: 10,
        border: '1px solid #aaa',
    },
    p1:{
        textAlign: 'left',
        paddingLeft: 80,
        fontColor: 'black',
    },
    button1:{
        backgroundColor: 'pink',
        color: 'black',
        width: '35%',
        borderRadius:40,
        marginTop: 10,
    },
    button2:{
        backgroundColor: '#9400D3',
        color: 'black',
        width: '35%',
        borderRadius:40,
    },
}));


export default function SignIn() {
    const classes = useStyles();
    const auth = useSelector(state => state.auth); //global stateを呼び出すため,Dev toolをみて決めてる
    const dispatch = useDispatch();
    const firebase = useFirebase();

    const signInWithGoogle = () => {
        firebase
            .login({
                provider: "google",
                type: "popup",
            })
            .then(() => {
                dispatch({ type: "USE_PROFILE" });
                dispatch(push('/top'));
            });
    };


    return (
        <div className={classes.root}>
            <Header/>
            <Grid >
                <Grid item xs={5} className={classes.grid}>
                    <Paper className={classes.paper}>
                        <form>
                            <h1>Welcome back!</h1>
                            <p>Please sign in below to continue</p>
                            <p className={classes.p1}>Email address</p>
                            <input
                                type="text"
                                name="Email"
                                className={classes.input1}
                            /><br></br>
                            <p className={classes.p1}>Password</p>
                            <input
                                type="password"
                                name="password"
                                className={classes.input}
                            /><br></br>
                            <Button classes={{root: classes.button1,}} type="submit">
                                Sign in
                            </Button>
                            <p>or</p>
                            <Button classes={{root: classes.button2,}}
                                    onClick={(event) => {
                                        event.preventDefault();
                                        signInWithGoogle();
                                    }} >
                                Sign in with Gmail
                            </Button><br></br>
                            <p >Forgot Password?</p>
                        </form>
                    </Paper>
                </Grid>
            </Grid>
            <Footer/>
        </div>

    );
}
Enter fullscreen mode Exit fullscreen mode

And here is my index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import { Provider } from 'react-redux';
import {configureStore} from './configureStore';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import { useHistory } from "react-router-dom";
import { createFirestoreInstance } from "redux-firestore";
import { BrowserRouter } from "react-router-dom";
import { useDispatch, useSelector } from 'react-redux';
import { ReactReduxFirebaseProvider } from "react-redux-firebase";
import { createStore, compose } from "redux";
import { rootReducer } from "./rootReducer";

  const firebaseConfig = {
    apiKey: "AIzaSyAOSBfTj_VQ4byWAAOWDhAsklmZtk2W_iE",
    authDomain: "stresstackle-599d9.firebaseapp.com",
    projectId: "stresstackle-599d9",
    storageBucket: "stresstackle-599d9.appspot.com",
    messagingSenderId: "930013144401",
    appId: "1:930013144401:web:79b25db79f4118359fdf70",
    measurementId: "G-J26Y6MYWV3"
  };

const rrfConfig = {
  userProfile: "users",
  useFirestoreForProfile: true,
};

firebase.initializeApp(firebaseConfig);
firebase.firestore();

export const auth = firebase.auth();

const initialState = {};
const store = createStore(rootReducer, initialState);

const rrfProps = {
  firebase,
  config: rrfConfig,
  dispatch: store.dispatch,
  createFirestoreInstance,
};

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <ReactReduxFirebaseProvider {...rrfProps}>
          <App />
      </ReactReduxFirebaseProvider>
    </Provider>
  </React.StrictMode>,
    document.getElementById('root')
    );
Enter fullscreen mode Exit fullscreen mode

And App.js

import React, { Suspense } from 'react';
import { BrowserRouter as Router,Switch, Route} from 'react-router-dom';
import Top from './components/Top';
import Contact from './components/Contact';
import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import { ConnectedRouter } from 'connected-react-router';
import {history} from './configureStore';
import { Provider } from 'react-redux'
import {configureStore} from './configureStore';
const store = configureStore();

const App = () => {


    return (
        <React.Fragment>
            <Provider store={store}>
                <ConnectedRouter history={history}>
                    <Switch>
                        <Route exact path="/" component={Top}/>
                    </Switch>
                    <Switch>
                        <Route exact path="/contact" component={Contact}/>
                    </Switch>
                    <Switch>
                        <Route exact path="/signup" component={SignUp}/>
                    </Switch>
                    <Switch>
                        <Route exact path="/signin" component={SignIn}/>
                    </Switch>

                    <Switch>
                        <Route exact path="/top" component={Top}/>
                    </Switch>
                </ConnectedRouter>
            </Provider>
        </React.Fragment>
    )

}
export default App;

Enter fullscreen mode Exit fullscreen mode

I use Header.js file to show the logout button.

import React from 'react'
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import {push} from "connected-react-router";
import {useDispatch, useSelector} from "react-redux";
import { useState } from 'react';
import { useEffect } from 'react'
import firebase from "firebase/app";


const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
    appBar:{
      height: 90,
    },
    button:{
        fontSize:50,
        display: 'flex',
        justifyContent: 'space-between',
    },
}));

export default function Header({children}) {
  const classes = useStyles();
    const auth = useSelector(state => state.auth); //global stateを呼び出すため,Dev toolをみて決めてる
    const dispatch = useDispatch();
    const [user, setUser] = useState(null);

    useEffect(() => {
        return firebase.auth().onAuthStateChanged(user => {
            setUser(user);
        });
    }, []);


    const logout = () => {
        firebase
            .logout({
                provider: "google",
                type: "popup",
            })
            .then(() => {
                dispatch({ type: "USE_PROFILE" });
                dispatch(push('/signin'));
            });
    };

    return (
            <React.Fragment>
                <div className={classes.root}>
                    <AppBar position="static" color='white' className={classes.appBar}>
                        <Toolbar className={classes.button}>
                            <p>ST</p>
                            {user ? (
                                <button onClick={logout}>Google Logout</button>
                            ) : (
                               <div></div>
                            )}
                        </Toolbar>
                    </AppBar>
                </div>
            </React.Fragment>
        );
    }

Enter fullscreen mode Exit fullscreen mode

So, when a user is signed in, onAuthStateChanged changes from null. onAuthStateChanged is here to check if the state for user sign-in has changed or not.

    const [user, setUser] = useState(null);

    useEffect(() => {
        return firebase.auth().onAuthStateChanged(user => {
            setUser(user);
        });
    }, []);
Enter fullscreen mode Exit fullscreen mode

If a user signed in,

   const logout = () => {
        firebase
            .logout({
                provider: "google",
                type: "popup",
            })
            .then(() => {
                dispatch({ type: "USE_PROFILE" });
                dispatch(push('/signin'));
            });
    };
Enter fullscreen mode Exit fullscreen mode

This function is called and my header will show the logout button. A lot of articles I found were doing way complicated things so it took time for me to figure this out. And I felt like Firebase official document was not too helpful for the logout function.

Hope this helps!

Top comments (0)