I am trying to learn firebase by reading their documentation. I have added login using google account and email password. When I click on log in, I am dispatching setLogInValue and the state is updating but getting the value of isLoggedIn: undefined. But when I first visit the page the value of isLoggedIn is null. I expect the value of isLoggedIn: true after clicking on log in and redirect to homepage but as I am getting undefined the routing is not working.
slice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
email: localStorage.getItem('email'),
isLoggedIn: localStorage.getItem('loggedInStatus'),
};
export const slice = createSlice({
name: 'slice',
initialState,
reducers: {
setLogInValue: (state, action) => {
state.email = localStorage.setItem('email', action.payload);
state.isLoggedIn = localStorage.setItem('loggedInStatus', true);
},
},
});
export const { setLogInValue } = slice.actions;
export default slice.reducer;
Login.jsx
import React, { useState } from 'react';
import {
getAuth,
signInWithPopup,
signInWithEmailAndPassword,
GoogleAuthProvider,
} from 'firebase/auth';
import { useDispatch } from 'react-redux';
import { setLogInValue } from '../redux/slice';
import { useNavigate } from 'react-router-dom';
import { auth } from '../firebase/firebase';
const Login = () => {
const [input, setInput] = useState({ email: '', password: '' });
const inputHandler = event => {
setInput({ ...input, [event.target.name]: event.target.value });
};
const dispatch = useDispatch();
const navigate = useNavigate();
// const auth = getAuth();
const googleSignIn = () => {
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then(result => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
dispatch(setLogInValue(user.email));
// localStorage.setItem('loggedInStatus', true);
navigate('/', { replace: true });
})
.catch(error => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.customData.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
// ...
console.log(errorMessage);
});
};
const submitHandler = event => {
event.preventDefault();
// const auth = getAuth();
signInWithEmailAndPassword(auth, input.email, input.password)
.then(userCredential => {
// Signed in
const user = userCredential.user;
console.log(user);
dispatch(setLogInValue(input.email));
setInput({
email: '',
password: '',
});
navigate('/', { replace: true });
})
.catch(error => {
const errorCode = error.code;
const errorMessage = error.message;
console.log(errorMessage);
});
};
return (
<div className="container">
<form
className="w-75 mx-auto mt-5"
onSubmit={event => submitHandler(event)}>
<div className="form-floating mb-3">
<input
name="email"
type="email"
className="form-control"
placeholder="[email protected]"
value={input.email}
onChange={inputHandler}
/>
<label>Email address</label>
</div>
<div className="form-floating">
<input
name="password"
type="password"
className="form-control"
placeholder="Password"
value={input.password}
onChange={inputHandler}
/>
<label>Password</label>
</div>
<button
type="submit"
className="btn btn-primary btn-lg d-block mx-auto mt-3">
Log in
</button>
</form>
<button
className="btn btn-primary btn-lg d-block mx-auto mt-3"
onClick={googleSignIn}>
Log in With Google
</button>
</div>
);
};
export default Login;
Home.jsx
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import 'bootstrap-icons/font/bootstrap-icons.css';
import { Routes, Route, Navigate } from 'react-router-dom';
import Nav from './components/Nav';
import Home from './pages/Home';
import Login from './pages/Login';
import { useSelector } from 'react-redux';
const App = () => {
const { isLoggedIn } = useSelector(state => state.info);
console.log('App:', isLoggedIn);
let routes;
if (isLoggedIn) {
routes = (
<>
<Nav />
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</>
);
} else {
routes = (
<>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</Routes>
</>
);
}
return <>{routes}</>;
};
export default App;
Nav.jsx
import React from 'react';
import { Link } from 'react-router-dom';
const Nav = () => {
return (
<nav className="navbar navbar-expand-lg bg-light ">
<div className="container">
<Link className="navbar-brand" to="/">
Navbar
</Link>
<Link className="nav-link" to="/">
Home
</Link>
</div>
</nav>
);
};
export default Nav;
Why I am getting undefined instead of "true/false/" of isLoggedIn value from the localStorage? How can I fix that?
CodePudding user response:
The problem is in the code in 'slice.js':
setLogInValue: (state, action) => {
state.email = localStorage.setItem('email', action.payload);
state.isLoggedIn = localStorage.setItem('loggedInStatus', true); // <<<< Problem here: function localStorage.setItem return 'undefined' value
},
so you should fix like this:
setLogInValue: (state, action) => {
localStorage.setItem('loggedInStatus', true)
localStorage.setItem('email', action.payload);
state.email = action.payload;
state.isLoggedIn = true;
},