не удается получить обновленную информацию профиля с помощью firebase после входа по электронной почте

#javascript #firebase #react-native #firebase-authentication

#javascript #firebase #react-native #firebase-аутентификация

Вопрос:

В настоящее время я разрабатываю приложение с использованием react native, и мне удалось создать страницу входа и регистрации, но моя проблема заключается в следующем. После создания пользователя с электронной почтой и паролем с использованием метода firebase я хотел бы обновить информацию профиля (DisplayName), чтобы отобразить ее на домашней странице. Но кажется, что страница перенаправляется на домашнюю страницу после регистрации без обновления

Я установил прослушиватель в своем стеке навигатора для отображения страниц входа / регистрации или домашней страницы относительно значения user.

Обновление будет установлено правильно, если я закрою приложение и перезагружу его после первой успешной регистрации.

мой код следующий за основным кодом стека

 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>
  
  

код для обработки метода регистрации :

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

  

код на домашней странице, я также установил прослушиватель пользователя.
Я также попытался вызвать метод: auth().CurrentUser;
Но у меня возникла та же проблема: для имени дисплея на первом дисплее было установлено значение null, и мне пришлось закрыть и перезагрузить приложение, чтобы иметь возможность его отображать.

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

  

результат журнала показывает, что DisplayName равно нулю, поэтому я предполагаю, что процесс регистрации перенаправляется на домашний адрес перед обновлением значения.

У кого-нибудь есть идея, как я могу получить значение обновления на экране домашней страницы?

Заранее спасибо

Ответ №1:

Информация о профиле пользователя получается из его токена ID, который Firebase получает, затем пользователь входит в систему (или создается), а затем автоматически обновляется каждый час. Если профиль пользователя обновляется в течение этого часа, клиент может показывать устаревшую информацию профиля, пока не обновит токен.

Вы можете принудительно обновить токен,:

  1. Выход пользователя и повторный вход.
  2. Вызов User.reload или User.getIdToken(true) .

Оба этих случая заставляют клиента обновлять токен ID и, таким образом, получать последний профиль с серверов.

Комментарии:

1. спасибо за ответ. если я хочу использовать метод user.reload, как я могу реализовать его на домашней странице. должен ли я также установить прослушиватель для onAuthStateChanged и, если пользователь существует, перезагрузить его? Используя DB для сохранения отображаемого имени, лучше ли обновлять эту информацию в режиме реального времени?

Ответ №2:

попробуйте это.

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

вот мой код регистрации. Я просто обновляю профиль с помощью адреса электронной почты прямо сейчас, поскольку у меня нет другого ввода для отображаемого имени. Я также использую 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>
  );
}
  

слушатель:

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

Комментарии:

1. Я хочу зарегистрироваться, поэтому создаю нового пользователя. создание выполнено правильно, я вижу нового пользователя в консоли firebase. Моя проблема в обновлении, я не могу получить обновленные значения при первой загрузке домашней страницы после регистрации. мне нужно закрыть приложение и перезагрузить его. Похоже, что обновление является асинхронным, поэтому я перенаправляю перед завершением. Но я не могу заставить его работать хорошо..

2. итак, если вы введете консоль в onAuthChange и используете новое электронное письмо для регистрации. вы что-нибудь получаете?

3. создание нового пользователя или логин работают хорошо. также ошибка, если электронная почта уже используется, или другие ошибки в порядке. Проблема заключается не в создании пользователей или их входе в систему. Это касается только обновления их информации, чтобы отобразить их при первой загрузке!

4. извините за это. я только что обновил свой ответ. проверил это с моей стороны, и это работает для меня.

5. код, который вы изменяете, я не могу использовать, потому что функция handleregister не имеет хука setUser. для этой функции регистрации не требуется значение пользователя. Он обрабатывает только процесс регистрации, в котором находится слушатель для пользователя App.js и здесь перехват setUser используется для проверки того, зарегистрирован ли пользователь или нет, чтобы отобразить правильный маршрут.