cant get the updated profile info with firebase after signIn with email

Viewed 1115

I am currently developping an app using react native and i could manage to have a login and sign up page but my problem is the following. After create user with email and password using firebase method, i would like to update the profile info (displayName) in order to display it in the home page. But it seems that the page redirect to the home page after sign up without the update done

I have set a listener on my navigator stack to display login/signup pages or Home page regarding the value of user.

the Update is correctly set if i close the app and reload it after the first sign up success.

my code is the following the main stack code

function onAuthStateChange(user) {
  setUser(user);
  if (initializing) setInitializing(false);
}
useEffect(() => {
  const subscriber = auth().onAuthStateChanged(onAuthStateChange);
  return subscriber;
}, [];

if (initializing) {
return <LoadingScreen />

if (!user) {
return (
  <NavigationCOntainer>
     <AuthStackScreen />
  </NavigationCOntainer>
 );
}

return (
 <NavigationCOntainer>
    <DrawerStackScreen />
 </NavigationCOntainer>
  

the code to handle the sign up method :

function handgleRegister() {
  auth()
    .createUserWithEmailAndPassword(email, password)
    .then(userCred => {
       return userCred.user.updateProfile({
           displayName: name,
       });
    })
    .catch(e => {
    ...
    ...
    });
}

the code in the Home page, i also set a listener of user. I also have tried by calling the method : auth().currentUser; But i got the same problem, the displayName at the first display was set to null and i had to close and reload the app to be able to display it.

function onAuthStateChange(user) {
  console.log(user);
}
useEffect(() => {
  const subscriber = auth().onAuthStateChanged(onAuthStateChange);
  return subscriber;
}, [];

the result of the log shows that displayName is null so i assume the sign up process redirect to the home before updating the value.

Does someone has an idea how i can manage to get the update value on the Home page screen?

Thanks in advance

2 Answers

The user's profile information is gotten from their ID token, which Firebase gets then the user signs in (or is created) and then automatically refreshes every hour. If the user's profile is updated within that hour, the client may be showing outdated profile information until it refreshes the token.

You can force the refresh of a token by:

  1. Signing the user out and in again.
  2. Calling User.reload or User.getIdToken(true).

Both of these cases force the client to refresh the ID token, and thus get the latest profile from the servers.

try this.

function handgleRegister() {
  auth()
    .createUserWithEmailAndPassword(email, password)
    .then(userCred => {
       userCred.user.updateProfile({
           displayName: name,
       }).then(()=>{
       setUser(auth().currentUser());
    };
    })
    .catch(e => {
    ...
    ...
    });
}

here's my signup code. I'm just update the profile with the email address right now since i don't have another input for display name. I'm also using redux toolkit.

import React, { Component, useEffect } from "react";
import { View } from "react-native";
import { Button, Input } from "react-native-elements";
import Icon from "react-native-vector-icons/FontAwesome";
import { Dimensions } from "react-native";
import auth from "@react-native-firebase/auth";
import { useDispatch, useSelector } from "react-redux";
import {
  clearLoginInfo,
  updateLoginInfo,
  signInWithEmailAndPassword,
} from "../login/LoginSlice";

export default function SignupScreen(props) {
  const { navigation } = props;
  const [username, setUsername] = React.useState("");
  const [password, setPassword] = React.useState("");
  const [passwordErrorMsg, setPasswordErrorMsg] = React.useState("");
  const [usernameErrorMsg, setUsernameErrorMsg] = React.useState("");
  const [securedText, setSecuredTtext] = React.useState(true);
  const dispatch = useDispatch();

  function onAuthStateChanged(user) {
    console.log("on user change", user);
  }

  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);

  const signIn = (e) => {
    auth()
      .createUserWithEmailAndPassword(e.username, e.password)
      .then((user) => {
        console.log("user = ", user);
        user.user
          .updateProfile({
            displayName: e.username,
            photoURL: "abc.com",
          })
          .then(() => {
            const currentUser = auth().currentUser;
            console.log("current user ", auth().currentUser);
            dispatch(
              updateLoginInfo({
                displayName: currentUser.displayName,
                photoURL: currentUser.photoURL,
              })
            );
          });
      })
      .catch((error) => {
        if (error.code === "auth/email-already-in-use") {
          setUsernameErrorMsg("That email address is already in use!");
        }
        if (error.code === "auth/invalid-email") {
          setUsernameErrorMsg("That email address is invalid!");
        }
        if (error.code === "auth/weak-password") {
          setPasswordErrorMsg("please choose a stronger password");
        }

        console.error(error);
      });
  };

  const handlePasswordChange = (val) => {
    setPassword(val);
  };

  const handleUserNameChange = (val) => {
    setUsername(val);
  };

  const doSignin = () => {
    signIn({ username, password });
  };
  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignContent: "center",
        alignItems: "center",
      }}
    >
      <Input
        placeholder="Email"
        errorMessage={usernameErrorMsg}
        value={username}
        leftIcon={{ type: "font-awesome", name: "envelope" }}
        onChangeText={handleUserNameChange}
      />
      <Input
        placeholder="Password"
        errorMessage={passwordErrorMsg}
        errorStyle={{ color: "red" }}
        value={password}
        leftIcon={<Icon name="lock" size={40} color="black" />}
        rightIcon={
          securedText ? (
            <Icon
              name="eye"
              size={32}
              onPress={() => setSecuredTtext(!securedText)}
              color="black"
            />
          ) : (
            <Icon
              name="eye-slash"
              size={32}
              onPress={() => setSecuredTtext(!securedText)}
              color="black"
            />
          )
        }
        onChangeText={handlePasswordChange}
        secureTextEntry={securedText}
      />
      <Button
        title="Sign up"
        onPress={() => doSignin()}
        buttonStyle={{ backgroundColor: "#eda621" }}
        style={{ width: Dimensions.get("window").width * 0.5 }}
      />
      <Button
        title="Back to Sign in"
        style={{ width: Dimensions.get("window").width * 0.5, marginTop: 10 }}
        onPress={() => navigation.navigate("Signin")}
      />
    </View>
  );
}

listener:

useEffect(()=>{
   if (user != null && user.displayName != '') {
     navigation.navigate("Home");
   },
   [user]});
Related