I'm new to react/firebase and I've recently been working on a project that involves a user signing into the website in order to access different aspects of a navigation bar, however for some reason, everytime a user logs in, they are briefly shown the correct navigation bar as well as are logged in, but shortly thereafter, they are logged out and sent back to the login page. Debugging the code, I found that for some reason, once a user clicks on the sign in button, the handleSignout function is ran along with the handleform submission function.
Attached is my Navbar along with the signout function because of the Sign out button in it. When I remove the onClick = {handleSignout()} from the sign out button, the user is not instantly signed out, but it defeats the purpose of having the button.
import {
Nav,
NavLink,
Bars,
NavMenu,
NavBtnLink,
} from './Navbar';
import { auth, fdb } from '../../firebase';
import { signOut } from 'firebase/auth';
import { updateDoc, doc } from 'firebase/firestore';
import { useContext } from 'react';
import { AuthContext } from '../../context/auth';
import { useNavigate } from 'react-router-dom';
const Navbar = () => {
const Navigate = useNavigate();
const {user} = useContext(AuthContext);
const handleSignout = async() => {
await updateDoc(doc(fdb,'users', auth.currentUser.uid), {
isOnline: false,
});
await signOut(auth);
Navigate('/Login')
};
return(
<Nav>
<NavLink to='/'>
<h1>logo</h1>
</NavLink>
{user ? (
<>
<Bars />
<NavMenu>
<NavLink to= '/Listings'>
Listings
</NavLink>
<NavLink to= '/Post'>
Post
</NavLink>
<NavLink to= '/contact'>
Contact
</NavLink>
<NavLink to= '/profile'>
Profile
</NavLink>
<NavBtnLink to='/' onClick={handleSignout()}>
Log Out
</NavBtnLink>
</NavMenu>
</>
) : (
<>
<NavMenu>
<NavBtnLink to='/Login'>
Log In / Register
</NavBtnLink>
</NavMenu>
</>
)}
</Nav>
)
};
export default Navbar;
Here is my login.js
import React from 'react'
import { useRef, useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { auth, fdb } from '../firebase'
import { signInWithEmailAndPassword } from 'firebase/auth'
import { updateDoc, doc } from 'firebase/firestore'
const Login = () => {
const emailRef = useRef();
const errRef = useRef();
const [email, setEmail] = useState('');
const [pwd, setPwd] = useState('');
const [errMsg, setErrMsg] = useState('');
const Navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
try {
const userinfo = await signInWithEmailAndPassword(auth,email,pwd);
await updateDoc(doc(fdb, 'users', userinfo.user.uid),{
isOnline: true,
})
Navigate('/')
} catch (e) {
alert(e)
}
}
return (
<div>
<div className="loginBody">
<p ref = {errRef} className= {errMsg ? "errmsg" : "offscreen"} aria-live="assertive">{errMsg}</p>
<h1 className='loginHeader'>Login</h1>
<form onSubmit={handleSubmit}>
<div className="email">
<label htmlFor="email" id='userLabel'>Email</label>
<br/>
<input
type="text"
id="email"
ref = {emailRef}
autoComplete = "off"
onChange = {((e)=> setEmail(e.target.value))}
value={email}
required
/>
</div>
<div className="pwd">
<label htmlFor="password">Password</label>
<br/>
<input
type="password"
id="password"
autoComplete = "off"
onChange = {((e)=> setPwd(e.target.value))}
value={pwd}
required
/>
</div>
<button id='signIn'>Sign In</button>
</form>
<p className='needAcc'>
Need an Account? <br/>
<span className="line">
<Link to="/Register" id='signUpLink'>Sign Up</Link>
</span>
</p>
</div>
</div>
)
}
export default Login
CodePudding user response:
This code:
<NavBtnLink to='/' onClick={handleSignout()}>
Should be:
<NavBtnLink to='/' onClick={handleSignout}>
By adding the parentheses (()
) you are immediately invoking handleSignout
, instead of only once the user clicks the button.
Also see the ReactJs documentation on handling events.