Firebase Realtime DB에서 읽어 온 데이터 Redux store에 업데이트 하기 (Redux-thunk 이용)

Ava Kim·2022년 6월 22일
2

이번 Redux 토이 프로젝트에 Firebase DB를 이용하는데, ref와 onValue를 이용해 데이터 읽어 오는 부분에서 굉장히 애를 먹었다.

결론적으로는 내가 파이어베이스 onValue나 리덕스 createAsyncThunk가 어떤 값을 return하고 어떤 특성을 가지고 있는지 제대로 모르는 상태에서 사용해서 겪은 문제였다. 공식문서 튜토리얼을 열심히 따라가는 것에 더해서, 내가 사용하는 method가 어떤 특성을 가지고 있는지 조금 더 꼼꼼하게 살펴보고 사용해야 한다는 걸 다시 한 번 배웠다.

개인적 기록이기도 하지만, 혹시나 아래와 비슷한 케이스 겪는 분들에게 조금이나마 도움이 될까 싶어 블로그에 기록한다.

첫 번째 시도

save, delete와 마찬가지로 fetch에도 createAsyncThunk를 이용해서 아래와 같이 코드를 짰는데, 리턴된 result가 undefined로 뜨는 에러가 발생했다.

내가 fetch 자체를 잘못한 건가 해서 console.log로 출력해 보니 데이터 자체는 잘 출력되었다.

그래서 DevTool로 확인해 봤더니 onValue가 끝나기 전에 result가 assign 되는게 문제였다.

export const fetchJournals = createAsyncThunk(
  'journals/fetchJournals',
  (userId) => {
    let result;
    const query = ref(db, `users/${userId}/journals`);
    onValue(query, (snapshot) => {
      result = snapshot.val();
    })
    return result;
  }
);

두 번째 시도

async / await를 사용하려고 했으나 열심히 찾아본 결과 onValue는 데이터가 변할 때마다 호출되기 때문에 promise를 리턴하지 않으므로 async/await는 사용 불가했다.

세 번째 시도

두번째 시도에서 힌트를 얻어서, createAsyncThunk가 아닌 normal thunk를 이용했더니 해결 됐다. 아래는 최종 코드인데, snapshot.val()으로 받아온 result 값을 dispatch를 이용해 state에 업데이트 하면 된다.

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { getDatabase, ref, set, remove, onValue } from 'firebase/database';
import { firebaseApp } from '../../service/firebase';

const db = getDatabase(firebaseApp);

const initialState = { posts: {}, status: 'idle', error: null };

export const fetchJournals = (userId) => {
  return (dispatch) => {
    const query = ref(db, `users/${userId}/journals`);
    onValue(query, (snapshot) => {
      const result = snapshot.val();
      dispatch(journalAdded(result));
    });
  };
};

//나머지 코드 생략

export const journalsSlice = createSlice({
  name: 'journals',
  initialState,
  reducers: {
    journalAdded(state, action) {
      state.posts = action.payload;
    },
  },
});

export const { journalAdded, journalDeleted, moodAdded } =
  journalsSlice.actions;

export default journalsSlice.reducer;
profile
FE developer | self-believer | philomath

2개의 댓글

comment-user-thumbnail
2022년 12월 27일

토이프로젝트 중인데 너무 큰 도움이 됐어요. 글 써주셔서 정말 감사합니다ㅜㅜㅜ

1개의 답글