Skip to content

Instantly share code, notes, and snippets.

@marcus-gomes-v
Created April 11, 2023 09:46
Show Gist options
  • Save marcus-gomes-v/2900e8a052a6f5064bebac01646da721 to your computer and use it in GitHub Desktop.
Save marcus-gomes-v/2900e8a052a6f5064bebac01646da721 to your computer and use it in GitHub Desktop.
Example to Use AuthContext with Firebase
//LoggedIn Page
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { useAuth } from '../context/AuthUserContext';
const LoggedIn = () => {
const { authUser, loading, signOut } = useAuth();
const router = useRouter();
// Listen for changes on loading and authUser, redirect if needed
useEffect(() => {
if (!loading && !authUser)
router.push('/')
}, [authUser, loading, router])
return (
<>
{
loading ?
<div className='flex justify-center'>
Loading...
</div> :
<>
I'm Logged
</>
}
</>
)
}
export default LoggedIn;
// AuthUserContext
import { createContext, useContext } from 'react'
import useFirebaseAuth from '../lib/useFirebaseAuth';
const authUserContext: any = createContext({
authUser: {},
loading: true,
signInWithEmailAndPassword: async () => {},
createUserWithEmailAndPassword: async () => {},
loginWithGoogle: async () => {},
signOut: async () => {}
});
export function AuthUserProvider({ children }: any) {
const auth = useFirebaseAuth();
return <authUserContext.Provider value={auth}>{children}</authUserContext.Provider>;
}
export const useAuth: any = () => useContext(authUserContext);
//useFirebaseAuth
import router from 'next/router';
import { useState, useEffect } from 'react'
import firebase from './firebase';
import { iUser } from '../typings';
const formatAuthUser = (user: any) => ({
uid: user.uid,
email: user.email,
name: user.displayName || '',
imageUrl: user.photoURL || '/images/avatar/placeholder.svg',
code: '',
type: 'user',
teams: []
});
export default function useFirebaseAuth() {
const [authUser, setAuthUser] = useState<iUser>();
const [loading, setLoading] = useState(true);
const authStateChanged = async (authState: any) => {
if (!authState) {
setLoading(false)
return;
}
setLoading(true)
var formattedUser: iUser = formatAuthUser(authState) as iUser;
setAuthUser(formattedUser);
setLoading(false);
};
const clear = () => {
setAuthUser(undefined);
setLoading(true);
};
const signInWithEmailAndPassword = (email: any, password: any) =>
firebase.auth().signInWithEmailAndPassword(email, password);
const createUserWithEmailAndPassword = (email: any, password: any) =>
firebase.auth().createUserWithEmailAndPassword(email, password);
const provider = new firebase.auth.GoogleAuthProvider();
const loginWithGoogle = () => firebase.auth().signInWithPopup(provider)
const signOut = () => firebase.auth().signOut().then(() => router.push('/')).then(clear);
useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged(authStateChanged);
return () => unsubscribe();
}, []);
return {
authUser,
loading,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signOut,
loginWithGoogle
};
}
// Page to Authenticate the User
import { faGoogle } from "@fortawesome/free-brands-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from 'react';
import { useRouter } from 'next/router';
import Link from "next/link";
import { useAuth } from "../../context/AuthUserContext";
export default function Authentication() {
const { signInWithEmailAndPassword, loginWithGoogle } = useAuth();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState(null);
const router = useRouter();
const emailAndPasswordLogin = (event: any) => {
setError(null)
signInWithEmailAndPassword(email, password)
.then((authUser: any) => {
console.log("Success. The user is created in firebase")
router.push('/dashboard');
})
.catch((error: any) => {
setError(error.message)
});
event.preventDefault();
};
const googleLogin = (event: any) => {
setError(null)
loginWithGoogle()
.then((authUser: any) => {
console.log("Success. The user is created in firebase")
router.push('/dashboard');
})
.catch((error: any) => {
setError(error.message)
});
event.preventDefault();
};
return (
<>
<div className="flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8">
<div className="sm:mx-auto sm:w-full sm:max-w-md text-vibrant-blue-600">
<div className="flex justify-center">
</div>
<h2 className="mt-3 text-center text-3xl font-bold tracking-tight text-gray-700">Access your account</h2>
</div>
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<form className="space-y-6" onSubmit={emailAndPasswordLogin}>
{error && <>error</>}
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email
</label>
<div className="mt-1">
<input
id="email"
name="email"
type="email"
autoComplete="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
required
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-vibrant-blue-500 focus:outline-none focus:ring-vibrant-blue-500 sm:text-sm"
/>
</div>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Password
</label>
<div className="mt-1">
<input
id="password"
name="password"
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
autoComplete="current-password"
required
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-vibrant-blue-500 focus:outline-none focus:ring-vibrant-blue-500 sm:text-sm"
/>
</div>
</div>
<div className="flex items-center justify-between">
<div className="text-sm">
<Link href="/sign_up">
<a className="font-medium text-vibrant-blue-600 hover:text-vibrant-blue-500">
Create an account
</a>
</Link>
</div>
{/* <div className="text-sm">
<a href="#" className="font-medium text-vibrant-blue-600 hover:text-vibrant-blue-500">
Forgot your password?
</a>
</div> */}
</div>
<div>
<button
type="submit"
className="flex w-full justify-center rounded-md border border-transparent bg-vibrant-blue-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-vibrant-blue-700 focus:outline-none focus:ring-2 focus:ring-vibrant-blue-500 focus:ring-offset-2"
>
Login
</button>
</div>
</form>
<div className="mt-6">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center text-sm">
<span className="bg-white px-2 text-gray-500">Or access with</span>
</div>
</div>
<div className="mt-6 grid grid-cols-1 gap-3">
<div>
<a
onClick={googleLogin}
className="inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-500 shadow-sm hover:bg-gray-50"
>
<span className="inline-flex align-middle ">
<FontAwesomeIcon icon={faGoogle} className={`h-4 w-4 mr-3`} /> Login with Google
</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment