How to render the name of the user in the profile page after signup using react firebase authentication?

I am a beginner in react js and I was implementing firebase authentication in my react app for sign up, login and redirect to homepage with react router. But when I enter the username, email id and password of a new user and click “sign up”, it’s taking me to the homepage and displaying “Login Please” on the first render. Only when I refresh the page again I am able to get “Welcome, ‘user_name’ “.

Intitial render of the homepage after sign up

Homepage after refresh

app.js

import './App.css';
import Views from './Routes/Views';
import {BrowserRouter} from 'react-router-dom'

function App() {
  return (
    <BrowserRouter>
      <Views />
    </BrowserRouter>
  );
}

export default App;

views.jsx

import { React, useEffect, useState } from "react";
import { Routes, Route } from "react-router-dom";
import { LoginSignup } from "../Components/LoginSignup/LoginSignup";
import { HomePage } from "../Components/HomePage/HomePage";
import { auth } from "../config/firebase";

const Views = () => {
  const [userName, setUserName] = useState("");
  useEffect(() => {
    auth.onAuthStateChanged((accountUser) => {
      if (accountUser) {
        setUserName(accountUser.displayName);
      } else {
        setUserName("");
      }
      console.log(accountUser.displayName);
    });
  });
  return (
    <Routes>
      <Route path="https://stackoverflow.com/" element={<LoginSignup />} />
      <Route path="/home" element={<HomePage name={userName} />} />
      <Route path="*" element={<div>404 Not Found!</div>} />
    </Routes>
  );
};

export default Views;

LoginSignup.jsx

import React, { useState, useRef, useEffect } from "react";
import "./LoginSignup.css";
import {
  faCheck,
  faTimes,
  faInfoCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import { auth } from "../../config/firebase";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";

import { useNavigate } from "react-router-dom";

import user_icon from "../Assets/person.png";
import email_icon from "../Assets/email.png";
import password_icon from "../Assets/password.png";

const USER_REGEX = /^[A-z][A-z0-9-_]{3,23}$/;
const PWD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%]).{8,24}$/;
const EMAIL_REGEX = /^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/;

export const LoginSignup = () => {
  const navigate = useNavigate();
  const userRef = useRef();
  const errRef = useRef();

  const [action, setAction] = useState("Sign Up");
  const [user, setUser] = useState("");
  const [validName, setValidName] = useState(false);
  const [userFocus, setUserFocus] = useState(false);

  const [email, setEmail] = useState("");
  const [validEmail, setValidEmail] = useState(false);
  const [emailFocus, setEmailFocus] = useState(false);

  const [password, setPassword] = useState("");
  const [validPassword, setValidPassword] = useState(false);
  const [passwordFocus, setPasswordFocus] = useState(false);

  const [errMsg, setErrMsg] = useState("");
  const [success, setSuccess] = useState(false);

  useEffect(() => {
    userRef.current.focus();
  }, []);

  useEffect(() => {
    setValidName(USER_REGEX.test(user));
  }, [user]);

  useEffect(() => {
    setValidPassword(PWD_REGEX.test(password));
  }, [password]);

  useEffect(() => {
    setValidEmail(EMAIL_REGEX.test(email));
  }, [email]);

  useEffect(() => {
    setErrMsg("");
  }, [user, password, email]);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const v1 = USER_REGEX.test(user);
    const v2 = PWD_REGEX.test(password);
    const v3 = EMAIL_REGEX.test(email);
    if (!v1 || !v2 || !v3) {
      setErrMsg("Invalid Entry");
      return;
    }
    createUserWithEmailAndPassword(auth, email, password)
      .then(async (res) => {
        const accountUser = res.user;
        await updateProfile(accountUser, {
          displayName: user,
        });
        navigate("/home");
      })
      .catch((err) => {
        setErrMsg(err.message);
      });
  };

  return (
    <div className="loginPage">
      <div className="titleAnimated">
        <span className="text first-text">Welcome To </span>
        <span className="text second-text">IntelliGuide</span>
      </div>
      <div className="container">
        <p ref={errRef} className={errMsg ? "errMsg" : "offscreen"}></p>
        <div className="header">
          <div className="text">{action}</div>
          <div className="underline"> </div>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="inputs">
            {action === "Login" ? (
              <div></div>
            ) : (
              <>
                <div className="labelStyle">
                  <label htmlFor="username">
                    Username:
                    <FontAwesomeIcon
                      icon={faCheck}
                      className={validName ? "valid" : "hide"}
                    />
                    <FontAwesomeIcon
                      icon={faTimes}
                      className={validName || !user ? "hide" : "invalid"}
                    />
                  </label>
                </div>
                <div className="input">
                  <img src={user_icon} alt="" />
                  <input
                    type="text"
                    id='username'
                    ref={userRef}
                    autoComplete="off"
                    onChange={(e) => setUser(e.target.value)}
                    required
                    aria-invalid={validName ? "false" : "true"}
                    aria-describedby='uidnote'
                    onFocus={() => setUserFocus(true)}
                    onBlur={() => setUserFocus(true)}
                  />
                </div>
                <p
                  id='uidnote'
                  className={
                    userFocus && user && !validName
                      ? "instructions"
                      : "offscreen"
                  }
                >
                  <FontAwesomeIcon icon={faInfoCircle} />
                  4 to 24 characters.
                  <br />
                  Must begin with a letter.
                  <br />
                  Letters, numbers, underscores, hyphens allowed.
                </p>
              </>
            )}
            <>
              <div className="labelStyle">
                <label htmlFor="email">
                  Email Id:
                  <span className={validEmail ? "valid" : "hide"}>
                    <FontAwesomeIcon icon={faCheck} />
                  </span>
                  <span className={validEmail || !email ? "hide" : "invalid"}>
                    <FontAwesomeIcon icon={faTimes} />
                  </span>
                </label>
              </div>
              <div className="input">
                <img src={email_icon} alt="" />
                <input
                  type="email"
                  id='email'
                  autoComplete="off"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  aria-invalid={validEmail ? "false" : "true"}
                  aria-describedby='emailnote'
                  onFocus={() => setEmailFocus(true)}
                  onBlur={() => setEmailFocus(false)}
                  required
                />
              </div>
            </>
            <>
              <div className="labelStyle">
                <label htmlFor="password">
                  Password:
                  <span className={validPassword ? "valid" : "hide"}>
                    <FontAwesomeIcon icon={faCheck} />
                  </span>
                  <span
                    className={validPassword || !password ? "hide" : "invalid"}
                  >
                    <FontAwesomeIcon icon={faTimes} />
                  </span>
                </label>
              </div>
              <div className="input">
                <img src={password_icon} alt="" />
                <input
                  type="password"
                  id='password'
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  aria-invalid={validPassword ? "false" : "true"}
                  aria-describedby='pwdnote'
                  onFocus={() => setPasswordFocus(true)}
                  onBlur={() => setPasswordFocus(false)}
                  required
                />
              </div>
              <p
                id='pwdnote'
                className={
                  passwordFocus && !validPassword ? "instructions" : "offscreen"
                }
              >
                <FontAwesomeIcon icon={faInfoCircle} />
                8 to 24 characters.
                <br />
                Must include uppercase and lowercase letters, a number and a
                special character.
                <br />
                Allowed special characters:{" "}
                <span aria-label="exclamation mark">!</span>{" "}
                <span aria-label="at symbol">@</span>{" "}
                <span aria-label="hashtag">#</span>{" "}
                <span aria-label="dollar sign">$</span>{" "}
                <span aria-label="percent">%</span>
              </p>
            </>
            {action === "Sign Up" ? (
              <div className="hiddenClass"></div>
            ) : (
              <div className="forgot-password">
                Lost Password? <span>Click Here!</span>
              </div>
            )}
            <div className="submit-container">
              <button
                className="submit"
                disabled={
                  !validName || !validPassword || !validEmail ? true : false
                }
                onClick={() => {
                  setAction("Sign Up");
                }}
              >
                Sign Up
              </button>
              <button
                className="submit"
                onClick={() => {
                  setAction("Login");
                }}
              >
                Login
              </button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
};


"HomePage.jsx"

import React from "react";
import "./HomePage.css";

export const HomePage = (props) => {
  return (
    <div className="containerHome">
      <h1>HomePage</h1>
      <h2>{props.name ? `Welcome, ${props.name}` : "Login Please"}</h2>
    </div>
  );
};

Since I am really new to firebase authentication I don’t know what to change in the views.jsx file. I was following a youtube video to learn these concepts. I was expecting the name of the user who creates the account to be displayed on the homepage without refreshing the homepage. But as things stand “Welcome, ‘user_name'” is only displayed if I refresh the page.

Leave a Comment