Search code examples
react-nativereact-reduximmutable.jsredux-actions

How to fetch data from firestore with immutable.js and redux-actions in react native?


I'm a beginner of react native. If you give me any advice, it would be helpful and I would appreciate you.

I'm trying to fetch data from firestore using react-native, immutable.js, react-redux, redux-actions also this codes follow ducks structure. The problem is that I can't get any data from firestore because data from firestore comes after reducer executed.

Even, I'm not sure if I could put firestore fetching method as second parameter of createAction.

Here's my code.


shared/index.js

import firebase from 'firebase/app';
import 'firebase/firestore'
import 'firebase/storage'

const config = {
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "..."
};

firebase.initializeApp(config);
const db = firebase.firestore();
const storage = firebase.storage();

export const getCategoryNames = () => {
  return db.collection('categories').get();
}

store/modules/categoryImgList

import {createAction, handleActions} from 'redux-actions';
import { Map, List } from 'immutable';

// firestore
import * as db from '../../shared';

// Action types
const GET_NAME = 'categoryImgList/GET_NAME';

// action creator
export const getName = createAction(GET_NAME, () => {
  db.getCategoryNames().then(data => {
    const arr = [];

    data.forEach(doc => {
        console.log(doc.data().name);
        arr.push(doc.data().name);
    });

    console.log('arr');
    console.log(arr);
  })
}); // none

const initialState = Map({
    name: List()
});

// Reducer
export default handleActions({
    [GET_NAME]: (state, { payload: name }) => {
      console.log(state);
      console.log({name});
      const item = Map({ name });
      return state.update('name', name => name.push(item));
    }
}, initialState);

Thank you so much!


Solution

  • I solved this issue by my self. I realized I needed redux-thunk to get async data. I installed redux-thunk and changed some code as below.

    import {handleActions} from 'redux-actions';
    
    // firestore
    import * as db from '../../shared';
    
    // Action types
    const GET_CATEGORY_NAME_PENDING = 'categoryImgList/GET_CATEGORY_NAME_PENDING';
    const GET_CATEGORY_NAME_SUCCESS = 'categoryImgList/GET_CATEGORY_NAME_SUCCESS';
    const GET_CATEGORY_NAME_FAILURE = 'categoryImgList/GET_CATEGORY_NAME_FAILURE';
    
    // action creator
    export const getName = () => async (dispatch) => {
      dispatch({type: GET_CATEGORY_NAME_PENDING});
      try {
        const response = await db.getCategoryNames();
    
        const arr = [];
        response.docs.forEach(res => {
            arr.push(res.id);
        });
        console.log(arr);
    
        dispatch({type: GET_CATEGORY_NAME_SUCCESS, payload: arr});
        return arr;
      } catch (e) {
          console.log(e);
          dispatch({type: GET_CATEGORY_NAME_FAILURE, payload: e});
      }
    }
    
    const initialState = {
      fetching: false,
      error: false,
      name: []
    };
    
    // Reducer
    export default handleActions({
      [GET_CATEGORY_NAME_PENDING]: (state) => ({ ...state, fetching: true, error: false }),
      [GET_CATEGORY_NAME_SUCCESS]: (state, action) => ({ ...state, fetching: false, name: action.payload }),
      [GET_CATEGORY_NAME_FAILURE]: (state) => ({ ...state, fetching: false, error: true })
    }, initialState);