Handle Firebase Auth persistence uisng Redux in React Application
When using Firebase authentication with React, the Firebase auth state (logged-in user) doesn't persist automatically across page reloads. To solve this issue, you need to use Firebase's onAuthStateChanged
method, which listens for authentication state changes, and update your Redux store (or component state) accordingly. Here's how to handle Firebase auth persistence:
Step 1: Firebase Auth Persistence
Firebase automatically persists authentication state using web storage (localStorage by default). However, you still need to listen for changes when the app is loaded to ensure the correct auth state is applied.
To enable this, use onAuthStateChanged
when your app starts:
import { useEffect } from 'react';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import { useDispatch } from 'react-redux';
import { setUser, clearUser } from './store/authSlice'; // Redux actions for setting user state
const App = () => {
const dispatch = useDispatch();
const auth = getAuth();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, dispatch to store
dispatch(setUser({
uid: user.uid,
email: user.email,
displayName: user.displayName,
}));
} else {
// User is signed out, clear the user from Redux store
dispatch(clearUser());
}
});
// Cleanup subscription on unmount
return () => unsubscribe();
}, [auth, dispatch]);
return (
<div>
{/* Rest of your app */}
</div>
);
};
export default App;
Step 2: Create Redux Slice for User Authentication
To manage the Firebase user state in Redux, create a slice that will handle user login/logout:
// src/store/authSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface UserState {
uid: string | null;
email: string | null;
displayName: string | null;
}
const initialState: UserState = {
uid: null,
email: null,
displayName: null,
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
setUser: (state, action: PayloadAction<UserState>) => {
state.uid = action.payload.uid;
state.email = action.payload.email;
state.displayName = action.payload.displayName;
},
clearUser: (state) => {
state.uid = null;
state.email = null;
state.displayName = null;
},
},
});
export const { setUser, clearUser } = authSlice.actions;
export default authSlice.reducer;
Step 3: Configure Firebase Auth Persistence Strategy (Optional)
By default, Firebase persists the auth state using localStorage
. You can change this persistence strategy to sessionStorage
or none
if needed.
import { getAuth, setPersistence, browserLocalPersistence, browserSessionPersistence } from 'firebase/auth';
const auth = getAuth();
setPersistence(auth, browserLocalPersistence) // or browserSessionPersistence
.then(() => {
// Firebase auth state is persisted in localStorage or sessionStorage
})
.catch((error) => {
console.error('Failed to set persistence:', error);
});
Step 4: Persist Redux State
You can use redux-persist
(as mentioned earlier) to persist your Redux state to localStorage
, which will include the user's authentication state:
// src/store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; // localStorage
import authReducer from './authSlice';
const persistConfig = {
key: 'auth',
storage,
};
const persistedAuthReducer = persistReducer(persistConfig, authReducer);
export const store = configureStore({
reducer: {
auth: persistedAuthReducer,
},
});
export const persistor = persistStore(store);
Step 5: Usage in Your App
Once everything is set up, the Firebase authentication state will be checked on app initialization using onAuthStateChanged
, and persisted to localStorage
using redux-persist
. The Redux store will handle the rest, ensuring the user state persists even on page reload.
Summary
Use
onAuthStateChanged
: Listen for changes in the Firebase auth state and update Redux or component state accordingly.Persist Redux state: Use
redux-persist
to persist Redux auth state to localStorage or sessionStorage.Optional Firebase Persistence: Customize Firebase's auth persistence strategy if needed (
localStorage
,sessionStorage
, ornone
).
This setup ensures that both Firebase authentication and your Redux store maintain state after page reloads.
Subscribe to my newsletter
Read articles from Gauss Coder directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by