Skip to content

Instantly share code, notes, and snippets.

@berbaroovez
Created February 25, 2022 06:54
Show Gist options
  • Save berbaroovez/d6832dc280d2e0b1eca4f862bcf7df09 to your computer and use it in GitHub Desktop.
Save berbaroovez/d6832dc280d2e0b1eca4f862bcf7df09 to your computer and use it in GitHub Desktop.
// Hook (use-auth.js)
import React, { useState, useEffect, useContext, createContext } from "react";
import * as firebase from "firebase/app";
import "firebase/auth";
// Add your Firebase credentials
firebase.initializeApp({
apiKey: "",
authDomain: "",
projectId: "",
appID: "",
});
interface ContextType {
user: User | null
signin: (email: string, password: string) => Promise<void>
signup : (email: string, password: string) => Promise<void>
signout : () => Promise<void>
sendPasswordResetEmail : (email: string) => Promise<void>
confirmPasswordReset : (code: string, password: string) => Promise<void>
}
const authContextDefaultValue: ContextType = {
user: null,
signin: () => Promise.reject("not implemented"),
signup: () => Promise.reject("not implemented"),
signout: () => Promise.reject("not implemented"),
sendPasswordResetEmail: () => Promise.reject("not implemented"),
confirmPasswordReset: () => Promise.reject("not implemented"),
};
const authContext = createContext<ContextType>(authContextDefaultValue);
// Provider component that wraps your app and makes auth object ...
// ... available to any child component that calls useAuth().
export function ProvideAuth: React.FC({ children }) {
const auth = useProvideAuth();
return <authContext.Provider value={auth}>{children}</authContext.Provider>;
}
// Hook for child components to get the auth object ...
// ... and re-render when it changes.
export const useAuth = () => {
return useContext(authContext);
};
// Provider hook that creates auth object and handles state
function useProvideAuth() {
const [user, setUser] = useState<User | null>(null);
// Wrap any Firebase methods we want to use making sure ...
// ... to save the user to state.
const signin = (email, password) => {
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((response) => {
setUser(response.user);
return response.user;
});
};
const signup = (email, password) => {
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((response) => {
setUser(response.user);
return response.user;
});
};
const signout = () => {
return firebase
.auth()
.signOut()
.then(() => {
setUser(false);
});
};
const sendPasswordResetEmail = (email) => {
return firebase
.auth()
.sendPasswordResetEmail(email)
.then(() => {
return true;
});
};
const confirmPasswordReset = (code, password) => {
return firebase
.auth()
.confirmPasswordReset(code, password)
.then(() => {
return true;
});
};
// Subscribe to user on mount
// Because this sets state in the callback it will cause any ...
// ... component that utilizes this hook to re-render with the ...
// ... latest auth object.
useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
setUser(user);
} else {
setUser(false);
}
});
// Cleanup subscription on unmount
return () => unsubscribe();
}, []);
// Return the user object and auth methods
return {
user,
signin,
signup,
signout,
sendPasswordResetEmail,
confirmPasswordReset,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment