1

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?

Stevetro
  • 1,933
  • 3
  • 16
  • 29
  • 1
    Firebase is not my area of expertise but you might want to look into the react-redux-firebase package. – Linda Paiste Apr 08 '21 at 18:12
  • Thanks for the tip, I've already looked at it, but I don't think the package works yet with the current version of react-native-firebase – Stevetro Apr 09 '21 at 08:03

1 Answers1

2

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.

lonecruisader
  • 408
  • 5
  • 13
  • The problem is that there is nothing such as a "user" component. But the auth store should be available from everywhere in the app. Thats why i need to sync it with the global redux store – Stevetro Apr 08 '21 at 11:00
  • Ok. If I understand your requirement , you should set the user on auth slice. And then get it from auth slice across any component using selectors , am I right? This user you are setting is the current user who is using the app ? Or could be any user on app ? I see you are setting in auth slice, so I deduced as should be for currently authenticated user. If so, basically you want to listen for changes in firestore for currently authenticated user in your app ? – lonecruisader Apr 08 '21 at 11:20
  • Correct, when the user register / login his account is create in firebase. At the same time there will be a node in firestore created for his userdata. This node should be fetched to my authState slice. When the data is changed the authState should automatically update, so i can use the data across the app. – Stevetro Apr 09 '21 at 08:08
  • Why don’t you crate a new AuthUser component and add this listener inside its useeffect. Then whenever firestore user changes , dispatch setuser. Add this AuthUser component within your Redux store component tree and return nothing but from this component – lonecruisader Apr 09 '21 at 11:32