Import this on top of application entry, such as pages/_app.tsx
NOTE: Make sure to import without resolving it
import '../lib/firebase'
// firebase.ts
// import { getAnalytics } from 'firebase/analytics';
import { getApp, getApps, initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
// import { getPerformance } from 'firebase/performance';
const firebaseAppConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
};
const isServer: boolean = typeof window === 'undefined';
if (!getApps().length) {
const _app = initializeApp(firebaseAppConfig);
if (isServer === false) {
if ('measurementId' in firebaseAppConfig) {
// getAnalytics(_app);
// getPerformance(_app);
}
}
}
const app = getApp();
export const auth = getAuth(app);
export default app;
Manage firebase auth state change.
Keep track of firebase user using react context provider state management.
Also contain some of firebase auth functions.
NOTE: You can extend the functions by adding new property at IAuthContext.
// AuthProviser.tsx
// import {...} from 'firebase/auth';
import { auth } from '../lib/firebase';
interface IAuthContext {
user: User | null;
error: Error | null;
loading: boolean;
signInWithEmail(email: string, password: string): void;
signInWithGoogle(): void;
signUp(email: string, password: string): void;
signOut(): void;
}
export const AuthContext = createContext<IAuthContext>({
user: null,
error: null,
loading: true,
signInWithEmail(email: string, password: string) {},
signInWithGoogle() {},
signUp(email: string, password: string) {},
signOut() {}
});
const AuthProvider: React.ReactWithChildren = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [error, setError] = useState<Error | null>(null);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
setLoading(true);
const unsub = onAuthStateChanged(auth, user => {
setUser(user);
setError(null);
setLoading(false);
});
return unsub;
}, []);
const _signInWithEmail = (email: string, password: string) => {
setLoading(true);
signInWithEmailAndPassword(auth, email, password)
.catch(setError)
.finally(() => setLoading(false));
};
const _signInWithGoogle = () => {
setLoading(true);
signInWithPopup(auth, new GoogleAuthProvider())
.catch(setError)
.finally(() => setLoading(false));
};
const _signUp = (email: string, password: string) => {
setLoading(true);
createUserWithEmailAndPassword(auth, email, password)
.catch(setError)
.finally(() => setLoading(false));
};
const _signOut = () => {
setLoading(true);
signOut(auth)
.catch(setError)
.finally(() => setLoading(false));
};
const value = {
user,
error,
loading,
signInWithEmail: _signInWithEmail,
signInWithGoogle: _signInWithGoogle,
signUp: _signUp,
signOut: _signOut
};
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};
export default AuthProvider;
// Context Usage
/** @ref AuthProvider value */
const { user } = useContext(AuthContext);