universal-firebase-auth
Version:
A reusable Firebase-based authentication package like Clerk for React with social login support (Google, Facebook, GitHub, LinkedIn, etc).
61 lines (51 loc) • 1.87 kB
JSX
import React, { createContext, useContext, useEffect, useState } from "react";
import {
onAuthStateChanged,
GoogleAuthProvider,
FacebookAuthProvider,
GithubAuthProvider,
OAuthProvider,
TwitterAuthProvider,
signInWithPopup,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
} from "firebase/auth";
import { initFirebase } from "../firebase";
const AuthContext = createContext();
export const AuthProvider = ({ children, config }) => {
const auth = initFirebase(config);
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (u) => {
setUser(u);
setLoading(false);
});
return () => unsub();
}, [auth]);
// ------------------ Public helpers ------------------
const providerFactory = {
google: new GoogleAuthProvider(),
facebook: new FacebookAuthProvider(),
github: new GithubAuthProvider(),
linkedin: new OAuthProvider("linkedin.com"), // needs LinkedIn enabled in Firebase console
twitter: new TwitterAuthProvider(),
};
const loginWithProvider = async (providerKey) => {
const provider = providerFactory[providerKey];
if (!provider) throw new Error(`Provider ${providerKey} is not supported.`);
await signInWithPopup(auth, provider);
};
const emailSignup = (email, password) => createUserWithEmailAndPassword(auth, email, password);
const emailLogin = (email, password) => signInWithEmailAndPassword(auth, email, password);
const logout = () => signOut(auth);
return (
<AuthContext.Provider
value={{ user, loading, loginWithProvider, emailSignup, emailLogin, logout }}
>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);