React Redux二次登录后头像不显示问题求助
React应用二次登录后头像无法显示问题修复
问题现象
注册完成自动登录时,Banner组件的Avatar能正常展示头像;但退出账号重新登录后,头像消失,控制台打印显示user.photoUrl为undefined。
核心原因
- 注册时未同步头像地址到Firebase用户Profile:注册流程仅更新了
displayName,未将用户输入的头像地址profpic保存到Firebase用户Profile中,导致二次登录时从Firebase获取的用户信息里photoURL字段为空。 - 字段映射需统一:登录时从Firebase取的是
photoURL(大写URL),但Redux中使用的是photoUrl(小写Url),虽JS大小写敏感,但核心问题仍是Firebase未持久化头像地址。
修复方案
1. 修改注册逻辑,同步头像到Firebase
在register方法中,更新用户Profile时同时设置photoURL,确保Firebase持久化头像地址:
const register = () => { if (!name) { return alert("Please enter your name!"); } auth .createUserWithEmailAndPassword(email, password) .then((userAuth) => { // 同时更新displayName和photoURL到Firebase用户Profile userAuth.user.updateProfile({ displayName: name, photoURL: profpic }).then(() => { dispatch( login({ email: userAuth.user.email, uid: userAuth.user.uid, displayName: name, photoUrl: profpic, }) ); }); }) .catch((error) => alert(error)); };
2. 统一登录逻辑的字段映射
确保登录时Firebase返回的photoURL正确映射到Redux的photoUrl字段:
const loginToApp = (e) => { e.preventDefault(); auth .signInWithEmailAndPassword(email, password) .then((userAuth) => { dispatch( login({ email: userAuth.user.email, uid: userAuth.user.uid, displayName: userAuth.user.displayName, photoUrl: userAuth.user.photoURL, // 映射Firebase字段到Redux字段 }) ); }) .catch((error) => alert(error)); };
3. 可选:Banner组件添加空值兜底
避免头像地址为空时出现异常,给Avatar添加默认内容:
// 替换Banner组件中的Avatar代码 <Avatar src={user?.photoUrl || ""}>{user?.displayName?.charAt(0)}</Avatar>
原代码参考
Banner组件原代码
import React from "react"; import "./Banner.css"; import { logout } from "./features/userSlice"; import { auth } from "./firebase"; import { useDispatch, useSelector } from "react-redux"; import { selectUser } from "./features/userSlice"; import logo from "./images/logo.png"; import SearchIcon from "@mui/icons-material/Search"; import { Avatar } from "@mui/material"; function Banner() { const user = useSelector(selectUser); console.log(user); const dispatch = useDispatch(); const logoutOfApp = () => { dispatch(logout()); auth.signOut(); }; console.log({ photoUrl: user?.photoUrl }); return ( <div className="banner"> <div class="banner_container"> <div className="banner_title"> <h1>Hobby Hunter</h1> <img src={logo} alt="Hobby Hunter logo" /> </div> {user ? ( <div className="banner_right"> <div className="header_search"> <SearchIcon /> <input placeholder="" type="text" /> </div> <h2 className="user">Welcome {user.displayName}!</h2> <Avatar src={user.photoUrl}></Avatar> <button onClick={logoutOfApp}>Logout</button> </div> ) : null} </div> </div> ); } export default Banner;
Login组件原代码
import React, { useState } from "react"; import { auth } from "./firebase"; import "./Login.css"; import { useDispatch } from "react-redux"; import { login } from "./features/userSlice"; import hpic from "./images/hpic.png"; function Login() { const [name, setName] = useState(""); const [profpic, setProfpic] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const dispatch = useDispatch(); const loginToApp = (e) => { e.preventDefault(); auth .signInWithEmailAndPassword(email, password) .then((userAuth) => { dispatch( login({ email: userAuth.user.email, uid: userAuth.user.uid, displayName: userAuth.user.displayName, photoUrl: userAuth.user.photoURL, }) ); }) .catch((error) => alert(error)); }; const register = () => { if (!name) { return alert("Please enter your name!"); } auth .createUserWithEmailAndPassword( email, password ) .then((userAuth) => { userAuth.user.updateProfile({ displayName: name }).then(() => { dispatch( login({ email: userAuth.user.email, uid: userAuth.user.uid, displayName: name, photoUrl: profpic, }) ); }); }) .catch((error) => alert(error)); }; return ( <div className="loginScreen"> <form> <input value={name} onChange={(e) => setName(e.target.value)} placeholder="Full name (required if registering)" type="text" /> <input value={profpic} onChange={(e) => setProfpic(e.target.value)} placeholder="Profile Pic (optional)" type="text" /> <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" type="email" /> <input value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" type="password" /> <button type="submit" onClick={loginToApp}> Sign In </button> <p> Not a member? <span className="login_register" onClick={register}> Register Now </span> </p> </form> <img src={hpic} alt="login pic" /> </div> ); } export default Login;
内容的提问来源于stack exchange,提问作者Jerm
相关产品推荐
相关产品推荐

