$30 off During Our Annual Pro Sale. View Details »

Google Sign in with Firebase in React 101

Google Sign in with Firebase in React 101

The link to the YouTube video explaining this slide: https://youtu.be/LzIu83lNk-c

Avatar for Michael

Michael

June 05, 2022
Tweet

More Decks by Michael

Other Decks in Programming

Transcript

  1. Summary - Develop a VOD service for indie animes 1.

    Set up a Firebase project 2. Develop a Google Sign In page 3. Update UI based on a sign in status a. By a react hook Spent: 6.5 hours
  2. 1. Set up a Firebase project • Create a project

    following by a official document • Enable Google Sign In following by the official documentation • npm install firebase to install the library for Web ◦ Use the version 9 of JS SDK
  3. 2. Develop a Google Sign In page • Use the

    plain firebase library ◦ Tried next-firebase-auth but gave up ▪ Couldn’t figure out how to set firebaseAdminInitConfig on a server side properly ▪ In the first place, Server Side Rendering hasn’t required so far • Challenge to develop: How to prepare a test account for Google OAuth? ◦ There is no way to create a test account for Google OAuth ▪ Stackoverflow question ◦ Create another account on Google for testing OAuth
  4. 2. Develop a Google Sign In page • Set up

    auth and Provider ◦ getAuth ◦ GoogleAuthProvider • Sign In on Pop up ◦ signInWithPopup import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth"; const app = initializeApp(firebaseConfig); const auth = getAuth(app); const provider = new GoogleAuthProvider(); // https://developers.google.com/identity/protocols/oauth2/scopes#people provider.addScope('https://www.googleapis.com/auth/contacts.readonly'); try { const result = await signInWithPopup(auth, provider); // This gives you a Google Access Token. You can use it to access the Google API. const credential = GoogleAuthProvider.credentialFromResult(result); if (credential == null) { console.error("Unexpected error: credential is null"); return; } const token = credential.accessToken; // The signed-in user info. const user = result.user; } catch (error) { // handle error
  5. 3. Update UI based on a sign in status •

    Related UI and UX ◦ Change a header based on whether a user signs in or signs out, or ◦ Redirect to a sign in page if a user hasn't signed in but accesses an unauthorized page • Challenges for me ◦ Manage the state of a user’s authentication on the client side ▪ React Hooks or HOC to implement
  6. 3. Update UI based on a sign in status •

    Manage the state of a user’s authentication on the client side ◦ auth.currentUser cannot be used for initial load because it’s not loaded yet ◦ auth.onAuthStateChanged((user) => {}) can be used to trigger re rendering const app = initializeApp(firebaseConfig); const auth = getAuth(app); auth.currentUser; // to get a current user auth.onAuthStateChanged((user) => { if (user) { // user is signed in } else { // user is signed out } });
  7. 3. Update UI based on a sign in status •

    Design React hook to get an auth React hook definitions class Auth { // … } export function useAuth(): [Auth, boolean] { const [user, setUser] = useState<User | null>(() => { return auth.currentUser; }); const [isInitialized, setInitialized] = useState<boolean>(false); useEffect(() => { auth.onAuthStateChanged((user) => { setUser(user); setInitialized(true); }); }, []); return [new Auth(user), isInitialized]; } Use case export const Header: React.FunctionComponent<{}> = () => { const [auth] = useAuth(); if (auth.isAnonymous) { return <UnauthHeader />; } return <AuthHeader auth={auth} />; };
  8. 3. Update UI based on a sign in status •

    Redirect to a sign in page if a user hasn’t signed in ◦ Design HOC when a sign in is required Use case export default requireAuth(AccountIndexPage); export function requireAuth(Component: React.ComponentType<Object>) { return ({ props, children }: any) => { const [auth, isAuthInitialized] = useAuth(); const router = useRouter(); useEffect(() => { if (isAuthInitialized && auth.isAnonymous) { router.push("/signin"); } }, [isAuthInitialized, auth, router]); return <Component {...props}>{children}</Component>; }; }