Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Google Sign in with Firebase in React 101

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

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>; }; }