naim-firebase-auth-wrapper
Version:
React components and hooks for Firebase Authentication and Firestore with Mantine UI
129 lines • 5.04 kB
JavaScript
import { useContext } from 'react';
import { GoogleAuthProvider, signInWithPopup, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut as firebaseSignOut, updateProfile, updatePassword, EmailAuthProvider, reauthenticateWithCredential, sendPasswordResetEmail, } from 'firebase/auth';
import { AuthContext } from '../components/AuthProvider';
import { getFirebaseAuth } from '../firebase/config';
import { handleServiceError } from '../utils/errorHandler';
import { createUserProfile, getUserProfile } from '../services/firestore';
/**
* Hook to access authentication context
*/
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
console.error('[useAuth] AuthContext not found. Make sure you are using AuthProvider.');
throw new Error('useAuth must be used within an AuthProvider');
}
// Ensure auth is available
const ensureAuth = () => {
const auth = getFirebaseAuth();
if (!auth) {
console.error('[useAuth] Firebase Auth not initialized');
throw new Error('Firebase Auth not initialized');
}
return auth;
};
// Sign in with Google
const signInWithGoogle = async () => {
try {
const auth = ensureAuth();
const provider = new GoogleAuthProvider();
const result = await signInWithPopup(auth, provider);
// Check if user profile exists in Firestore
const userProfile = await getUserProfile(result.user.uid);
// If user profile doesn't exist, create it
if (!userProfile) {
await createUserProfile(result.user.uid, {
uid: result.user.uid,
email: result.user.email || '',
displayName: result.user.displayName || '',
photoURL: result.user.photoURL || '',
organizations: [],
createdAt: new Date()
});
}
return result;
}
catch (error) {
console.error('[useAuth] Google sign-in error:', error);
throw handleServiceError(error, 'Failed to sign in with Google');
}
};
// Sign in with email and password
const signInWithEmail = async (email, password) => {
try {
const auth = ensureAuth();
return await signInWithEmailAndPassword(auth, email, password);
}
catch (error) {
console.error('[useAuth] Email sign-in error:', error);
throw handleServiceError(error, 'Failed to sign in with email and password');
}
};
// Sign up with email and password
const signUp = async (email, password, displayName) => {
try {
const auth = ensureAuth();
const result = await createUserWithEmailAndPassword(auth, email, password);
// Update profile if displayName is provided
if (displayName && result.user) {
await updateProfile(result.user, { displayName });
}
return result;
}
catch (error) {
console.error('[useAuth] Sign-up error:', error);
throw handleServiceError(error, 'Failed to sign up');
}
};
// Update user password
const updateUserPassword = async (currentPassword, newPassword) => {
try {
const auth = ensureAuth();
const user = auth.currentUser;
if (!user || !user.email) {
throw new Error('No authenticated user found');
}
// Re-authenticate user before changing password
const credential = EmailAuthProvider.credential(user.email, currentPassword);
await reauthenticateWithCredential(user, credential);
// Update password
await updatePassword(user, newPassword);
}
catch (error) {
console.error('[useAuth] Password update error:', error);
throw handleServiceError(error, 'Failed to update password');
}
};
// Sign out
const signOut = async () => {
try {
const auth = ensureAuth();
await firebaseSignOut(auth);
}
catch (error) {
console.error('[useAuth] Sign-out error:', error);
throw handleServiceError(error, 'Failed to sign out');
}
};
// Send password reset email
const forgotPassword = async (email) => {
try {
const auth = ensureAuth();
await sendPasswordResetEmail(auth, email);
}
catch (error) {
console.error('[useAuth] Password reset error:', error);
throw handleServiceError(error, 'Failed to send password reset email');
}
};
return {
...context,
signInWithGoogle,
signInWithEmail,
signUp,
updateUserPassword,
signOut,
forgotPassword
};
};
//# sourceMappingURL=useAuth.js.map