Back-end/Firebase

[노마드코더] #5 Edit Profile

성중 2022. 4. 8. 18:43

Get My Own Posts

프로필 페이지에 내가 쓴 글 목록을 구현해보자

 

[src/components/Router.js]

...
            <Route exact path="/profile">
              <Profile userObj={props.userObj} />
            </Route>
...

사용자를 식별하기 위해 Profile에 userObj를 props로 넘겨준다

 

[src/routes/Profile.js]

...
  const getMyPosts = async () => {
    const posts = await dbService
      .collection("posts")
      .where("creatorId", "==", `${props.userObj.uid}`)
      .orderBy("createdAt", "desc")
      .get();
    console.log(posts.docs.map((doc) => doc.data()));
  };
  useEffect(() => {
    getMyPosts();
});
...

where로 id를 대조해 본인이 작성한 글만, orderBy로 최신순으로 비동기로 불러오자

 

NoSQL 방식이기 때문에 콘솔을 보면 조작을 위한 index를 만들어 달라고 나오는데..
해당 링크로 들어가 FireStore에 색인(index)을 자동으로 생성해주자
콘솔에 본인이 작성한 글만 찍힌다!

 

Update Profile

Firebase에서 사용자 관리하기🔽

 

Firebase에서 사용자 관리하기  |  Firebase Documentation

Join Firebase at Google I/O online May 11-12, 2022. Register now 의견 보내기 Firebase에서 사용자 관리하기 사용자 생성하기 Firebase 프로젝트에서 신규 사용자를 생성할 때는 createUserWithEmailAndPassword 메서드를 호

firebase.google.com

  • Firebase의 updateProfile 메서드는 닉네임과 프로필 사진 정도만 변경할 수 있는 한계가 있다
  • 더 많은 커스텀을 하려면 FireStore에 user 고유 collection을 생성해 조작하는 방식을 쓰자!

 

[src/components/Navigation.js]

<Link to="/profile">{props.userObj.displayName}의 Profile</Link>

userObj를 props로 받아서 displayName으로 사용자 닉네임을 불러온다

 

[src/routes/Profile.js]

...
  const [newDisplayName, setNewDisplayName] = useState(
    props.userObj.displayName
);
...
  const onChange = (event) => {
    const {
      target: { value },
    } = event;
    setNewDisplayName(value);
  };
  const onSubmit = async (event) => {
    event.preventDefault();
    // form의 닉네임을 변경했다면 업데이트
    if (props.userObj.displayName !== newDisplayName) {
      await props.userObj.updateProfile({
        displayName: newDisplayName,
      });
    }
  };
  return (
    <>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          type="text"
          placeholder="Display name"
          value={newDisplayName}
        />
        <input type="submit" value="Update Profile" />
      </form>
      <button onClick={onLogOutClick}>Log Out</button>
    </>
  );
};
...

form에 displayName을 state 데이터로 불러와 updateProfile로 변경할 수 있도록 해준다

 

Refresh User

  • 현재 업데이트한 이름을 보려면 새로고침이 필요하다
  • 곳곳에 authService.currentUser.uid를 호출하지 않고 props로 넘기는 이유는 메서드를 불러오는 소스를 최대한 하나로 통합하기 위함이다!
  • 따라서 userObj를 바로 갱신하려면 데이터가 선언된 최상단 파일(App.js)에 갱신 함수를 정의하고, props로 내려줘야 한다

 

[src/components/App.js]

...
function App() {
  const [init, setInit] = useState(false); // 로딩 상태
  const [userObj, setUserObj] = useState(null);
  useEffect(() => {
    // 사용자 정보 변화 감지
    authService.onAuthStateChanged((user) => {
      if (user) {
        setUserObj({
          displayName: user.displayName,
          uid: user.uid,
          // updateProfile 메서드 재정의
          updateProfile: (args) => user.updateProfile(args),
        });
      } else {
        setUserObj(null);
      }
      setInit(true);
    });
  }, []);
  const refreshUser = () => {
    const user = authService.currentUser;
    setUserObj({
      displayName: user.displayName,
      uid: user.uid,
      updateProfile: (args) => user.updateProfile(args),
    });
};
...

처음부터 authService에서 사용하는 객체 데이터 및 메서드만 state 데이터로 정의해주고,

해당 값들만 authService.currrentUser에서 받아와 갱신해주는 함수를 작성

* user 객체 데이터가 방대하기 때문에, 전체를 받으면 React가 변경된 값을 인식하지 못할 수 있다

 

[src/routes/Profile.js]

...
  const onSubmit = async (event) => {
    event.preventDefault();
    // form의 닉네임을 변경했다면 업데이트
    if (props.userObj.displayName !== newDisplayName) {
      await props.userObj.updateProfile({
        displayName: newDisplayName,
      });
      props.refreshUser();
    }
};
...

props로 내려서 호출해주면 새로고침 없이 갱신된 userObj가 렌더링 된다!

 

본 내용은 노마드코더의 '트위터 클론코딩'을 바탕으로 작성되었습니다.

'Back-end > Firebase' 카테고리의 다른 글

[노마드코더] #6 Finishing Up  (0) 2022.04.10
[노마드코더] #4 File Upload  (0) 2022.04.06
[노마드코더] #3 CRUD  (0) 2022.03.28
[노마드코더] #2 Authentication  (0) 2022.03.18
[노마드코더] #1 Introduction  (0) 2022.03.11