[korea-map-note] firestore onSnapshot을 이용한 데이터 실시간 감지

쏘소·2022년 9월 29일
0

프로젝트

목록 보기
3/18
post-custom-banner

메모 변경사항 지도에 실시간 반영 문제

Korea map note를 생성하면서, 메모를 추가하고 삭제할 때에 지도에 실시간으로 변경사항이 적용이 되지 않는 문제가 발생하였다.

이 문제를 해결하기 위해서 다음과 같은 3가지 방식을 생각하였다.

강제 리로드 방식

이 문제를 어떻게 해결해야 할지에 대한 고민을 하다가 처음엔 강제 리로드 방식을 생각하였다. 하지만 관련 포스트를 조금만 읽어봐도 이는 좋지 않은 방법이고, 코드를 잘못 짰다는 내용의 글을 읽을 수가 있다.

그리고 이 강제 리로드 방식은 웹페이지를 다시 리로드할 때 사용한다기보다는, 양식(폼)을 초기화할 때 더 많이 사용된다고 한다(reload()).

마지막으로, 데이터가 데이터베이스에 업로드 되고 리로드를 해주어야 변경사항이 제대로 적용될 수가 있는데 그냥 reload를 해버리면 아무 소용이 없다.

state 변경 hook 생성

따라서 두 번째 방법으로, state를 변경시켜 렌더링을 하는 방법이다.

하지만 이 방법 또한 데이터가 데이터베이스에 업로드 된 후 state를 변경 시켜주어야 하는데 이 또한 데이터가 데이터베이스에 적용되는 시점을 정확히 알 수가 없으니 적용하기 힘든 방법이었다.

firebase firestore, storage 데이터 감지 이벤트

그렇다면 메모 데이터를 저장하는 firestore와 blob 사진 데이터를 저장할 수 있는 storage의 데이터에 변경사항이 일어나면 이를 감지 할 수 있는 이벤트를 설정하는 것이 좋겠다는 생각이 들었다.

아니나 다를까, 찾아보니 실제로 해당 이벤트가 있었고, 다음과 같이 firestore의 데이터를 감지하는 onSnapshot 이벤트로 문제를 해결해줄 수가 있었다.

적용 후 코드

const KakaoMap = () => {
  useEffect(() => {
    const document = query(collection(firebaseDBService, userId))
    const snapShotHandler = () => {
      getDocsFromFirebase(userId).then((memoDocs) =>
        setMarkPosition((prevMarkPosition) => getMemoPositionFromFirebaseHandler(memoDocs, prevMarkPosition))
      )
    }

    const snapShotEvent = snapShotFirebaseData(document, snapShotHandler)

    return () => {
      snapShotEvent()
    }
  }, [setMarkPosition, userId])
  
  return (
    ```
    )
}
export const snapShotFirebaseData = (
  document: Query<DocumentData>,
  snapShotHandler: () => Promise<void> | Promise<void> | void
) => {
  const snapShotEvent = onSnapshot(document, snapShotHandler)
  return snapShotEvent
}

사이드 이펙트 중 하나인 이벤트이기 때문에 useEffect 에서 감지를 해주고 return을 통해서 컴포넌트 unmount 시에 이벤트 구독을 취소해주었다.

profile
개발하면서 행복하기
post-custom-banner

0개의 댓글