I am using firebase for authentication in my react application. I have an AuthContext as:
import React, { useContext, useState, useEffect } from 'react';
import { auth, storage, db } from '../firebase';
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [currentUserData, setCurrentUserData] = useState();
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
db.collection('users')
.doc(user.uid)
.onSnapshot((doc) => {
var data = doc.data();
setCurrentUserData(data);
});
setLoading(false);
});
return unsubscribe;
}, []);
signup function,
login function,
logout function
const value = {
currentUser,
currentUserData,
signup,
login,
logout,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
Whenever I signup/create a new user, I am also creating a document in 'users' collection in firestore with some default user fields along with uid from the firebase auth. I have a bunch of pages that requires some data from this firestore document for the current user that is currently logged in. I can get this user data in the currentUserData state for the first user that logs into the application. But when a user logs out and another user logs in, the currentUserData state holds the values fetched from firestore for the previously logged in user, not for the currently logged in user. I tried having a separate DataContext as well like:
import React, { useEffect, useState, useContext } from 'react';
import { db } from '../firebase';
import { useAuth } from './AuthContext';
const DataContext = React.createContext();
export function useData() {
return useContext(DataContext);
}
export function DataProvider({ children }) {
const [currentUserData, setCurrentUserData] = useState();
const [loading, setLoading] = useState(true);
//current user from AuthContext
const { currentUser } = useAuth();
useEffect(() => {
db.collection('users')
.doc(currentUser.uid)
.onSnapshot((doc) => {
var data = doc.data();
setCurrentUserData(data);
setLoading(false);
});
}, []);
const value = {
currentUserData,
};
return (
<DataContext.Provider value={value}>
{!loading && children}
</DataContext.Provider>
);
}
And in the corresponding App.js:
<Router>
<AuthProvider>
<DataProvider>
<Switch>
<PrivateRoute exact path='/' component={Home} />
.
.
.
</Switch>
</DataProvider>
</AuthProvider>
</Router>
Doing this also results in the same scenario. When a user logs out and another logs in, I still have the values of the previous user in the currentUserData state. However, the currentUser state in AuthContext works correcly. I am tired of fetching the user data in each and every component that needs user data for the logged in user. I wanted to fetch the data once and use it in whatever component that needs it. But I am having issues making it work. Is it something I am doing incorrectly?