'nextjs firebaseauth redirect before render page if logged in
I have a login page and an auth provider as follow
import * as yup from "yup";
import { useState } from 'react'
import { AuthErrorCodes } from 'firebase/auth'
import Cover from '../../components/Cover'
import Head from 'next/head'
import Headingblock from '../../components/Headingblock'
import Section from '../../components/Section'
import { authErrorCodesTranslation } from '../../config/firebase';
import { siteTitle } from '../_app'
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useRouter } from 'next/router';
import { useAuth } from "../../contexts/auth";
import { auth } from '../../config/firebase';
import { signInWithEmailAndPassword } from "firebase/auth";
import {useEffect} from 'react'
export default function Login() {
const [response, setResponse] = useState({});
const [user, userLoading] = useAuth();
const router = useRouter();
console.log(userLoading);
if (!userLoading && user)
router.push('/');
const schema = yup.object().shape({
email: yup.string().email('Adresse email invalide').required('Veuillez renseigner votre adresse email.'),
password: yup.string().required('Veuillez renseigner votre mot de passe')
});
const { register, handleSubmit, formState } = useForm({
resolver: yupResolver(schema),
});
const { errors } = formState;
const onSubmit = async (data) => {
await signInWithEmailAndPassword(auth, data.email, data.password)
.then(userCredential => {
router.push("/profile");
}).catch(error => {
const authErrorCode = Object.keys(AuthErrorCodes).find(k => AuthErrorCodes[k] === error.message);
let errorTranslation = authErrorCodesTranslation.GLOBAL_AUTH_ERROR;
if (authErrorCode !== undefined)
errorTranslation = authErrorCodesTranslation[authErrorCode];
setResponse({ status: 'error', message: errorTranslation });
})
}
return (
<>
<Head>
<title>{siteTitle} - Connexion</title>
</Head>
<Cover />
<Section>
<div className='container marginNTop100'>
<div style={{ padding: '3rem 1.5rem', background: 'white', boxShadow: '0 30px 50px 0 rgb(1 1 1 / 15%)' }}>
<Headingblock main="Connexion" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-row">
<div className="form-group col" style={formgroupStyle}>
<label style={labelStyle}>Adresse email</label>
<input {...register("email")} type="text" className='form-control' style={formcontrolStyle} />
<div className="invalid-feedback" style={invalidStyle}>{errors.email?.message}</div>
</div>
<div className="form-group col" style={formgroupStyle}>
<label style={labelStyle}>Mot de passe</label>
<input {...register("password")} type="password" className='form-control' style={formcontrolStyle} />
<div className="invalid-feedback" style={invalidStyle}>{errors.password?.message}</div>
</div>
</div>
<div className="form-group" style={formgroupStyle}>
<button type="submit" style={Object.assign(btnStyle, btnprimaryStyle)}>
Connexion
</button>
</div>
{
response.status === 'error' && <div style={Object.assign(alertStyle, alertDangerStyle)}>{response.message}</div>
}
</form>
</div>
</div>
</Section>
</>
)
}
import { createContext, useState, useEffect, useContext } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from '../config/firebase'
const AuthContext = createContext({ user: null, userLoading: true });
export const AuthProvider = ({ children }) => {
const [userLoading, setUserLoading] = useState(true);
const [user, setUser] = useState();
useEffect(() => {
return onAuthStateChanged(auth, (user) => {
console.log('autstatechanged');
if (user) {
console.log("1");
setUser(user);
setUserLoading(false);
// ...
} else {
console.log("2");
setUser(null);
}
});
}, []);
return (
<AuthContext.Provider value={[user, userLoading]}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
Once user is logged in I would like that page being not available anymore so I made a redirect once user is set and userloading is false but the page is rendering before redirect that causes a blink effect.
I wouldn't like return a loading screen I think It should be possible to not render login page if user is logged in
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
