본문 바로가기
Frontend/Project(개인 기록용)

firebase photoURL 사용하여 마이페이지 구현

by Johnny_gon 2023. 6. 8.
728x90
반응형

마이페이지 작업중에 아래 코드로 구현했더니 

user.accessToken 값이 있는데도 페이지 새로고침시에 login 페이지로 이동하는 것이다..

분명히 user정보가 있는데? 왜...

 
  useEffect(() => {
    if (!user.accessToken) {
      navigate("/login");
    } else {
      setCurrentImage(user.photoURL);
    }
  }, [user]);
 

 

 

 

개발도 구창을 확인해 보니
유저 정보가 비었다가 들어오는 걸 보니 통신 중에 딜레이 때문에 생기는 현상 같았다.

 

 

 

이 문제를 해결하기 위해서 reducer에서 isLoading 추가

기본값 false, 로그인,로그아웃시에 true로 세팅

 
  export const userSlice = createSlice({
    name: "user",
    initialState: {
      displayName: "",
      uid: "",
      accessToken: "",
      photoURL: "",
      isLoading: false,
    },
    reducers: {
      //로그인시에 데이터
      loginUser: (state, action) => {
        state.displayName = action.payload.displayName;
        state.uid = action.payload.uid;
        state.accessToken = action.payload.accessToken;
        state.photoURL = action.payload.photoURL;
        state.isLoading = true;
      },
      //user 로그아웃시에 값 비워줌
      clearUser: (state) => {
        state.displayName = "";
        state.uid = "";
        state.accessToken = "";
        state.isLoading = true;
      },
    },
  });
 
 
  const [currentImage, setCurrentImage] = useState("");
 
  useEffect(() => {
    //통신이 없는 순간에 코드가 실행되어서 login페이지로 이동되는 것을
    //방지하기 위해서 isLoading userSlice에추가
    //user가 변경될 때마다 if문 실행으로 새로고침시 로그인페이지 이동하는것 해결
    if (user.isLoading === true && user.accessToken === "") {
      navigate("/login");
    } else {
      //유저 정보 확인 되면 state에 프로필이미지 저장
      setCurrentImage(user.photoURL);
    }
  }, [user]);
 

 

 

react - Avatar 사용하여 유저 프로필 이미지 설정

         
         <Avatar
            size="100"
            round={true}
            src={currentImage}
          />
 

 

 

 

이미지 클릭시 업로드 기능 작업

 
  const ImageUpload = (e) => {
 
    var formData = new FormData();
    formData.append("file", e.target.files[0]); //XMLHtpRequest
    //콘솔로 formData 찍으면 빈 오브젝트로 출력// {}
    //for문으로 콘솔 찍어야 보여요..
    // for (const keyValu of formData) console.log(keyValu);
    axios
      .post("/api/user/profile/image", formData)
      .then((res) => {
        setCurrentImage(res.data.filePath);
      })
      .catch(() => {});
   };
 
 
   <MyPageDiv>
      <form>
        <label>
          <input
            type="file"
            accept="image/*"
            style={{ display: "none" }}
            onChange={ImageUpload}
          />
          <Avatar
            size="100"
            round={true}
            src={currentImage}
          />
        </label>
        <button onClick={saveProfileHanler}>저장</button>
      </form>
    </MyPageDiv>
 

 

 

 

server 코드 추가

 
  router.post(
    "/profile/image",
    setUpload("react-project/user"),
    (req, res, next) => {
      res.status(200).json({ success: true, filePath: res.req.file.location });
    }
  );
 

 

 

 

 

마이페이지 이미지 등록 확인할 수 있습니다.

 

 

 

 

 

새로고침시 이미지 초기화 되어 이미지 update 기능 추가해줍니다.

 
const saveProfileHanler = async (e) => {
    e.preventDefault();

    //firebase 이미지 저장 후 mongoDB 저장
    try {
      await firebase.auth().currentUser.updateProfile({
        //user 프로필 이미지추가
        photoURL: currentImage,
        uid: user.uid,
      });
    } catch (err) {
      return alert("프로필 저장에 실패하였습니다.");
    }
    let body = {
      photoURL: currentImage,
      uid: user.uid,
    };
    axios.post("/api/user/profile/update", body).then((res) => {
      if (res.data.success) {
        alert("프로필 저장에 성공하였습니다.");
        window.location.reload();
      } else {
        alert("프로필 저장에 실패하였습니다.");
      }
    });
  };
 

 

 

 

server 코드

 
  router.post("/profile/update", (req, res) => {
    let temp = {
      photoURL: req.body.photoURL,
    };
    User.updateOne({ uid: req.body.uid }, { $set: temp })
      .exec()
      .then(() => {
        res.status(200).json({ success: true });
      })
      .catch((err) => {
        res.status(400).json({ success: false });
      });
  });
 

 

728x90
반응형