Reputation: 12737
I created a react app using create-react-app
and configured a redux store with reducers. I also added firebase and my project works fine. The components can trigger an action that fetches a collection from firestore, and it in return, updates the redux store.
What is the best way to integrate firebase and redux store?
The way I am currently doing it, is to have a separate action that triggers the fetch/delete/onSnapshot from firebase, and handing a reference to dispatch
so that firebase function can take its time executing the command, then it can call dispatch with an action that updates the store.
But I wanted all of my actions in a single file, for a better (separation of concerns). Therefor, firebase can call dispatch but the action creator lives in my actions.js file. This way, I can later decide to change the action names in a single file, if I decided to do that.
The problem with this approach, is I will require a separate action to trigger the async function with firebase, and another action creator for when the promise is fulfilled.
What is a better approach to what I am doing?
const rootReducer = combineReducers({
cards: cardsReducer,
});
const store = createStore( rootReducer , {}, applyMiddleware(thunk));
export default store;
// I need this to be called from an action in actions.js
// therefor, I am exporting it, and also, I am handing it dispatch
// so it will call store.dispatch once data is ready
export const fetchCardsFromFirebase = async (dispatch) => {
const cardsCollection = collection(db, "cards");
const cardsSnapshot = await getDocs(roomsCollection);
const cards = roomsSnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id }));
// here I can either explicitly dispatch an action
/*
dispatch({
type: CARDS_FETCHED //this constant string will have to be imported
payload: cards
});
*/
// or I can let an action in actions.js do the above:
dispatch(cardsFetched(rooms)); //this function is imported from actions.js
}
import { FETCH_CARDS , CARDS_FETCHED } from "./types";
import { fetchCardsFromFirebase } from "../myFirebase";
export const fetchCards = () => async (dispatch) => {
fetchCardsFromFirebase(dispatch); // give firebase access to dispatch
dispatch({
type: FETCH_CARDS,
payload: {message: "fetching cards... please wait"}
});
};
const cardsFetched = (cards) => ({
action: CARDS_FETCHED,
payload: cards
});
Upvotes: 0
Views: 1310
Reputation: 44296
Generally, this is a very old style of Redux - modern Redux does not use switch..case reducers or ACTION_TYPES and switching to modern Redux will proably already save you 50% of your code.
That said, the official Redux Toolkit (RTK) also comes with RTK-Query, which is a data caching abstraction that should also work fine with firebase and will generate reducers, actions and even hooks automatically for you. (Hint: with firebase you will need to use queryFn
). That would save you a lot more code as well.
I would recommend you to follow the official Redux Tutorial which first shows modern Redux and in later chapters goes into RTK Query.
Upvotes: 1