Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

error authenticating with firebase and react js

I’m trying to create a simple registration and login system with firebase auth, but whenever I restart the site in console.log it appears that the user is saved, but the application returns him to the login page, as if he was not saved in the system.

App.jsx:

import { useState, useEffect } from 'react'
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { onAuthStateChanged } from 'firebase/auth'
import { auth } from './firebase'

// Pages
import SignUp from './pages/SignUp.jsx'
import SignIn from './pages/SignIn.jsx'
import Home from './pages/Home.jsx'

function App() {
  const [authUser, setAuthUser] = useState(null)

  useEffect(() => {
    const listen = onAuthStateChanged(auth, (user) => {
      if (user) {
        setAuthUser(user)
        console.log(user)
      } else {
        setAuthUser(null)
      }
    })
    return () => {
      listen()
    }
  }, [])

  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route path='/' element={authUser ? <Home/> : <Navigate to='signIn'/>}/>
          <Route path='/signup' element={<SignUp />} />
          <Route path='/signin' element={<SignIn />} />
        </Routes>
      </BrowserRouter>
    </div>
  )
}

export default App

SignIn.jsx:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { signInWithEmailAndPassword } from 'firebase/auth'
import React from 'react'
import { Link, useNavigate } from "react-router-dom"
import { useState } from 'react'
import { auth } from "../firebase.js"

const SignIn = () => {
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")
    const nav = useNavigate()

    const handleSubmit = async (e) => {
        e.preventDefault()
        try {
            const userCredential = await signInWithEmailAndPassword(auth, email, password)
            console.log(userCredential)
            nav('/')
        } catch (error) {
            console.log(error)
        }
    }

    return (
        <div className='min-h-[100vh] flex flex-col justify-center'>
            <form className='w-[80vw] flex flex-col items-center mx-auto p-5 bg-neutral-content rounded-md' onSubmit={handleSubmit}>
                <h1 className='text-2xl font-bold mb-4'>Sign-In</h1>
                <label className="input input-bordered rounded flex items-center gap-2 my-3" htmlFor='email'>
                    <input name="email" type="email" className="grow" placeholder="Digit your email" onChange={(e) => setEmail(e.target.value)} value={email} required />
                </label>
                <label className="input input-bordered rounded flex items-center gap-2 my-3">
                    <input type="text" className="grow" placeholder="Digit your password" onChange={(e) => setPassword(e.target.value)} required value={password} />
                </label>
                <Link to='/signUp' className='text-sm mb-2'>Não tenho conta. <span className='underline'>Cadastrar-se</span></Link>
                <input type="submit" value="Entrar" className='btn rounded mt-3' />
            </form>
        </div>
    )
}

export default SignIn

SignUp.jsx:

import { createUserWithEmailAndPassword } from 'firebase/auth'
import React from 'react'
import { Link, useNavigate } from "react-router-dom"
import { useState } from 'react'
import { auth } from '../firebase'

const SignUp = () => {
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")
    const [confirmKey, setConfirmKey] = useState("")
    const navigate = useNavigate()

    const handleSubmit = async(e) => {
        e.preventDefault()
        console.log(`email: ${email} | senha: ${password} | senha dnv: ${confirmKey}`)
        setEmail("")
        setPassword("")
        setConfirmKey("")
        try {
            const userCredentials = await createUserWithEmailAndPassword(auth, email, password)
            console.log(userCredentials)
            navigate('/')
        } catch (error) {   
            console.log(error)
        }
        
    }

    return (
        <div className='min-h-[100vh] flex flex-col justify-center'>
            <form className='w-[80vw] flex flex-col items-center mx-auto p-5 bg-neutral-content rounded-md' onSubmit={handleSubmit}>
                <h1 className='text-2xl font-bold mb-4'>Sign-up</h1>
                <label className="input input-bordered rounded flex items-center gap-2 my-3" htmlFor='email'>
                    <input name="email" type="email" className="grow" placeholder="Digit your email" onChange={(e) => setEmail(e.target.value)} value={email} required />
                </label>
                <label className="input input-bordered rounded flex items-center gap-2 my-3">
                    <input type="text" className="grow" placeholder="Digit your password" onChange={(e) => setPassword(e.target.value)} required value={password} />
                </label>
                <label className="input input-bordered rounded flex items-center gap-2 my-3">
                    <input type="text" className="grow" placeholder="Confirm your password" onChange={(e) => setConfirmKey(e.target.value)} required value={confirmKey} />
                </label>
                <Link to='/signin' className='text-sm mb-2'>Já tenho uma conta. <span className='underline'>Logar-se</span></Link>
                <input type="submit" value="Cadastrar" className='btn rounded mt-3' />
            </form>
        </div>
    )
}

export default SignUp

The home page is just a div written home, nothing much that disrupts the logic of the code.

>Solution :

That is happening due to Redirect is executed before onAuthStateChanged is executed and the user is set. It just uses your initial user’s value which is null in a useState initialization code.

You can add 1 extra useState flag-variable that will indicate if auth-check code is fired at least once, and then to reuse it with redirect logic:

const [isAuthReady, setIsAuthReady] = useState(false);

and

  useEffect(() => {
    const listen = onAuthStateChanged(auth, (user) => {
      if (user) {
        setAuthUser(user)
        console.log(user)
      } else {
        setAuthUser(null)
      }
      setIsAuthReady(true);
    })
    return () => {
      listen()
    }
  }, [])

And just before the return section of your App component add another return with

if (!isAuthReady) return <p>Loading...</p>

Or anything else you prefer.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading