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.
Once you successfully signed in, the logout button will show up on the header.
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>
);
}
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')
);
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;
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>
);
}
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);
});
}, []);
If a user signed in,
const logout = () => {
firebase
.logout({
provider: "google",
type: "popup",
})
.then(() => {
dispatch({ type: "USE_PROFILE" });
dispatch(push('/signin'));
});
};
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)