Home > other >  Email and Password Signup using firebase in a react app , the displayName of the user appears to be
Email and Password Signup using firebase in a react app , the displayName of the user appears to be

Time:10-08

I have an App component under which I have got three more component Login,Register,DashBoard and under the DashBoard component I have NavBar which has children as Content

Here is App.js

const App = () => {
  return (
    <div className="app">
      <Router>
        <Switch>
          <Route exact path="/" element={<Login />} />
          <Route exact path="/register" element={<Register />} />
          <Route exact path="/dashboard" element={<Dashboard />} />
        </Switch>
      </Router>
    </div>
  );
};
In Login.js component when a user login is successful then I'm storing the email and displayName into a user object in localStorage of the browser

Here is DashBoard.js

const Dashboard = () => {
  const { displayName, email } = JSON.parse(localStorage.getItem("user"));

  return (
    <NavBar displayName={displayName}>
      <Content></Content>
    </NavBar>
  );
};

Register.js

const Register = () => {
  const [register, setRegister] = useState({
    name: "",
    phoneNumber: "",
    email: "",
    password: "",
  });
  const navigate = useNavigate();
  const { name, phoneNumber, email, password } = register;
  const [user] = useAuthState(auth);

  const handleChange = (name) => (e) => {
    e.preventDefault();
    setRegister({ ...register, [name]: e.target.value });
  };

  useEffect(() => {
    if (loading) return;
    console.log(user);
    if (user) navigate("/dashboard", { replace: true });
  }, [user]);
  return (
    <div style={{ marginTop: "15rem" }}>
      <Container>
        <Row className="justify-content-lg-center">
          <Col xs>
            <FloatingLabel
              controlId="floatingInput"
              label="Name"
              className="mb-3"
            >
              <Form.Control
                type="text"
                placeholder="Doe joe"
                value={name}
                onChange={handleChange("name")}
              />
            </FloatingLabel>
            <FloatingLabel
              controlId="floatingPassword"
              label="Phone Number"
              className="mb-3"
            >
              <Form.Control
                type="number"
                placeholder="phoneNumber"
                value={phoneNumber}
                onChange={handleChange("phoneNumber")}
                name="email"
              />
            </FloatingLabel>
            <FloatingLabel
              controlId="floatingInput"
              label="Email Address"
              className="mb-3"
            >
              <Form.Control
                type="email"
                placeholder="Enter your Email.."
                value={email}
                onChange={handleChange("email")}
                name="email"
              />
            </FloatingLabel>
            <FloatingLabel
              controlId="floatingPassword"
              label="Password"
              className="mb-3"
            >
              <Form.Control
                type="password"
                placeholder="Password"
                value={password}
                onChange={handleChange("password")}
                name="phoneNumber"
              />
            </FloatingLabel>

            <Button
              variant="primary"
              onClick={() => {
                registerWithEmailAndPassword(
                  name,
                  phoneNumber,
                  email,
                  password
                );
                navigate("/");
              }}
            >
              Register
            </Button>
          </Col>
        </Row>
      </Container>
    </div>
  );
};

Here Firebase.js

const firebaseConfig = {
//firebase config
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

 //signIn Using google  

const logInWithEmailAndPassword = async (email, password) => {
  try {
    const res = await signInWithEmailAndPassword(auth, email, password);
    const user = res.user;
  } catch (err) {
    console.log(err);
    return err;
  }
};
const registerWithEmailAndPassword = async (
  name,
  phoneNumber,
  email,
  password
) => {
  try {
    const res = await createUserWithEmailAndPassword(
      auth,
      email,
      password,
      name,
      phoneNumber
    );
    const user = res.user;

    await updateProfile(auth.currentUser, {
      displayName: name,
    });
    await addDoc(collection(db, "users"), {
      uid: user.uid,
      name: name,
      phoneNumber: phoneNumber,
      authProvider: "local",
      email,
      password,
    });
  } catch (err) {
    console.error(err);
  }
};

   //logout
//exporting 

NavBar.js

const NavBar = (props) => {
  const [user] = useAuthState(auth); //react-firebase-hook/auth

  const navigate = useNavigate();
  const handleLogout = () => {
    logout();
  };
  useEffect(() => {
    if (!user) navigate("/");
  }, [user]);

  return (
    <>
      <Navbar bg="light" variant="light">
        <Container>
          <Navbar.Brand href="/dashboard">React-Bootstrap</Navbar.Brand>
          <Navbar.Toggle aria-controls="responsive-navbar-nav" />
          <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="me-auto"></Nav>
            <Nav>
              <Button variant="danger" onClick={handleLogout}>
                Logout
              </Button>
              <Nav.Link href="#deets"></Nav.Link>
              {user && (
                <Navbar.Text>Signed in as: {props.displayName}</Navbar.Text>
              )}
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
      {props.children}
    </>
  );
};

I'm displaying the name of the user in the Navbar component but after registering when the user is navigated to the root route which is login component which has an effect attached to it if the user then navigates to dashboard where the Navbar component will show the displayName but it is coming as null when I reload the page then it is showing the name. How can I show the displayName on initial render after registering when user is redirected to DashBoard

CodePudding user response:

You haven't included the NavBar component which you having issues with. It seems like a race condition in which the props are passed to NavBar before the values are set / retrieved. Perhaps try something like this in your NavBar component:

import { useEffect, useState } from 'react'
const NavBar = () => {

  const [displayName, setDisplayName] = useState('')
  const [email, setEmail] = useState('')

  // get the values when the component is rendered 
  useEffect(() => {
    const { displayName, email } = JSON.parse(localStorage.getItem("user"));
    setDisplayName(displayName)
    setEmail(email)
  }, [])

  return (
    <NavBar>
      <span>Email: {email}</span>
      <span>Display Name: {displayName}</span>
    </NavBar>
  );
};

CodePudding user response:

I kind of got a Solution to this, from the top of the component tree at App.js Added these lines

  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [user] = useAuthState(auth);

  useEffect(() => {
    setTimeout(() => {
      if (user !== null) {
        setName(user.displayName);
        setEmail(user.email);
      }
    }, 1000);
  }, [user]);

And then went on drilling down the props to the required component. Not a dependable solution but it is working for me right now

  • Related