본문 바로가기

Server/Firebase

<파이어베이스> 프로필 수정

 

 

1. 프로필 수정

* 프로필 가져오기

 - 사용자의 닉네임 또는 사용자명을 보여주고 싶다고 가정하자.

 

 - 우리는 현재 user객체를 userObj라는 객체로 사용하고 있다. (firebase.auth().currentUser)

 

 - 이 객체에는 여러가지 프로필 정보와 관련된 속성이 있다. 대표적으로 displayName과 email, photoURL이 있다. 필자는 구글로 로그인 했기 때문에 구글에서 사용하는 사용자명이 그대로 displayName에 담겨 있었다.

 

<li>
  <Link to="/profile">{userObj.displayName}의 프로필</Link>
</li>

 

 - 위와 같이 유저 객체를 이용하여 displayName 을 불러왔다. 하지만 userObj가 없다거나 displayName이 없을 경우 오류가 날 수 있으므로 아래와 같이 수정하였다.

<li>
  <Link to="/profile">
    {userObj?.displayName
      ? `${userObj.displayName}의 프로필`
      : "프로필"}
  </Link>
</li>

 

 

* 프로필 수정하기

 - 프로필을 수정하는 것 또한 매우 간단하다.

 

// Profile.js

  const onSubmit = async (event) => {
    event.preventDefault();
    if(userObj.displayName !== newDisplayName) {
      await userObj.updateProfile({
        displayName: newDisplayName
      })
      refreshUser();
    }

 

 - 유저 객체의 updateProfile 메소드를 사용해서 필요한 부분을 수정할 수 있다.

 

 - refreshUser 함수는 App.js에서 props로 내려온 함수이다. 이는 수정되고나서 수정된 이름이 렌더링 되도록 넣은 함수이다. 이런 함수가 필요한 이유는 우리는 현재 userObj라는 리액트에서 만들었던 객체를 쓰고 있기 때문에 파이어베이스 db내에 변경된 값으로 다시 바꿔줘야하기 때문이다.

 

 - 따라서 refreshUser함수는 아래와 같이 간단하게 만들 수 있다.

 

// App.js

const refreshUser = () => {
  setUserObj(authService.currentUser);
};

 

 - 위를 Profile.js까지 props로 내려준 후 사용하기만 하면 된다.

 

 - 하지만 안타깝게도 프로필을 수정해도 렌더링이 그대로인 것을 볼 수 있다. 이는 아래에서 해결하자.

 

* 버그 해결하기

 - 위와 같은 문제가 생기는 이유는 리액트의 동작 원리때문이다. 리액트는 변화된 값만을 감지해서 상태를 변화시키는데에 최적화 되어있다. 그러나 authService.currentUser 내에는 너무 많은 데이터가 담겨있고, 이를 리액트가 모두 하나하나 비교할 수는 없기 때문이다.

 

 - 따라서 userObj에 currentUser객체를 모두 넣지않고 필요한것만 넣어서 리액트가 비교하기 편하도록 설계해야한다.

 

 - 현재 우리가 필요한 currentUser의 속성과 메서드는 displayName, uid 와 updateProfile 메서드 뿐이다.

 

 - 따라서 처음 useEffect로 UserObj를 변경할때부터 위값만을 넣도록 만들어두자.

 

// App.js

function App() {
  const [init, setInit] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userObj, setUserObj] = useState(null);

  useEffect(() => {
    authService.onAuthStateChanged((user) => {
      if(user){
        setIsLoggedIn(true);
        setUserObj({
          displayName: user.displayName,
          uid: user.uid,
          updateProfile: (args) => user.updateProfile(args),
        });
      } else {
        setIsLoggedIn(false);
      }
      setInit(true)
    })
  }, [])

 

 - 위와 같이 displayName과 uid에는 원래 파이어베이스에서 제공하는 user객체의 그 속성을 그대로 넣어두었다. 메서드도 그대로 사용하기 위해서 위와 같이 할당하였다. 인자를 필요로 하는 메서드이기때문에 위와같이 넣으면 동일하게 동작할 것이다.

 

 - 이제 refreshUser을 수정하자.

 

// App.js

  const refreshUser = () => {
    const user = authService.currentUser;
    setUserObj({
      displayName: user.displayName,
      uid: user.uid,
      updateProfile: (args) => user.updateProfile(args),
    });
  };

 

 - 여기서도 동일하게 currentUser을 불러와서 UserObj에 넣어주기만 하면된다.

 

 - 위와같이하면 객체를 비교하여 리액트가 올바르게 렌더링하게된다.

 

 


 

 

 

참고

 

 

 

Firebase에서 사용자 관리하기

사용자 생성하기 Firebase 프로젝트에서 신규 사용자를 생성할 때는 createUserWithEmailAndPassword 메서드를 호출하는 방법과 Google 로그인 또는 Facebook 로그인과 같은 제휴 ID 공급업체를 이용해 사용자의

firebase.google.com

 

 

Watch Now - 노마드 코더 Nomad Coders

 

nomadcoders.co