Stevetro
Stevetro

Reputation: 1963

Handle onSnapshot subscription in createAsyncThunk

Currently i try to connect firebase / firestore to the redux store of my react-native project.

I've created a reducer with the createSlice function of @reduxjs/toolkit

const authSlide = createSlice({
  name: 'auth',
  initialState: initialState,
  reducers: {
    authLoading: state => {
      state.isLoading = true;
    },
    hasError: (state, action: PayloadAction<Error>) => {
      state = { ...state, error: action.payload, isLoading: false };
    },
  },
  extraReducers: builder => {
    builder.addCase(setUserData.pending, (state, action) => {});
    builder.addCase(setUserData.fulfilled, (state, action) => {});
    builder.addCase(setUserData.rejected, (state, action) => {});
  }
})

in the action of the setUserData reducer i want to subscribe to changes in firestore, so every time a change occurs the state should be updated.

I tried it with this code and its working for once, but not for future updates

export const getUserDataById = createAsyncThunk(
  'auth/getUserData',
  async (uid: string, { rejectWithValue }) =>
    new Promise<User>((resolve, reject) => {
      const unsubscribe = userRef.doc(uid).onSnapshot(
        snapshot => {
          const data = snapshot.data();
          if (snapshot.exists && data) {
            resolve({ uid, ...data });
          } else {
            reject({ name: 'Auth error', message: i18n.t('error.userNotFound') });
          }
        },
        error => reject(error),
      );
      listenerUnsubscribeList.push(unsubscribe);
    }),
);

Does anyone have an idea how I could solve the problem?

Upvotes: 1

Views: 881

Answers (1)

lonecruisader
lonecruisader

Reputation: 438

My suggestion would be to create a separate component to listen (inside its useeffect) to Firestore changes and dispatch events to the store when something changes. Having a subscriber inside createasyncthunk doesn't seem right.

Upvotes: 2

Related Questions