Skip to content

Instantly share code, notes, and snippets.

@koistya
Last active July 8, 2023 14:57
Show Gist options
  • Save koistya/d68710e09915efa7fa15af76a7e3e70a to your computer and use it in GitHub Desktop.
Save koistya/d68710e09915efa7fa15af76a7e3e70a to your computer and use it in GitHub Desktop.
Twitter auth flow using Firebase Auth (a.k.a. Google Identity Platform)

Resources

How to configure Twitter auth using Firebase Auth (a.k.a. Google Identity Platform)?

  • Create a new app in Twitter Developer Portal
    • Enable web auth flow, set website homepage, privacy policy, terms of use, and auth callback URLs
    • Copy save the API Key and API Secret somewhere
  • Create a Google Cloud project
    • Enable billing, enable Identity Platform
    • On the Identity Platform page add Twitter identity provider with API Key, API Secret from Twitter app
    • Add website domain to the list of whitelisted auth domains
    • Click App Settings, copy and save apiKey, authDomain somewhere to be used in the React app
  • In the React app...
    • Install firebase npm module
    • Add code that initializes Firebase app using apiKey, authDomain from GCP
    • Add a custom React callback hook that initiates Twitter login flow
    • Add a React hook that monitors for changes to the currently logged in user object (auth state)

How to initialize a Firebase app in the React app

core/firebase.ts

import { initializeApp } from "firebase/app";

export const app = initializeApp({
  apiKey: "xxx",
  authDomain: "xxx.firebaseapp.com" // or, customdomain.com with a few extra tweaks to the Next.js app
});

NOTE: Ensure that this code does not run on the server (during SSR)

How to access the currently logged-in user

core/firebase.ts

import { initializeApp } form "firebase/app";
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { useState, useEffect } from "react";

export const app = initializeApp({ ... });
export const auth = getAuth(app);

export function useCurrentUser() {
  const [me, setMe] = useState(auth.currentUser);

  useEffect(() => {
    return onAuthStateChanged(auth, user => {
      setMe(user);
    });
  }, []);

  return me;
}
import { useCurrentUser } from "../core/firebase";

export function Example(): JSX.Element {
  const me = useCurrentUser();

  return <p>Hello, {me?.displayName}</p>;
}

How to initiate the sign-in flow via Twitter

core/firebase.ts

import { initializeApp } form "firebase/app";
import { getAuth, onAuthStateChanged, TwitterAuthProvider } from "firebase/auth";
import { useState, useEffect } from "react";

export const app = initializeApp({ ... });
export const auth = getAuth(app);

export function useConnectTwitter() {
  return useCallback(() => {
    const provider = new TwitterAuthProvider();
    signInWithPopup(auth, provider);
  }, []);
}
import { useConnectTwitter } from "../core/firebase";

export function Example(): JSX.Element {
  const connectTwitter = useConnectTwitter();
  const me = useCurrentUser();

  return (
    <div>
      <button onClick={connectTwitter}>
        Connect Twitter
      </button>
    </div>
  );
}

How to obtain Twitter credentials for the current user

One way to obtain the credentials is at the time when user connects his twiter account (useConnectTwitter()):

async function connectTwitter() {
  const provider = new TwitterAuthProvider();
  const user = await signInWithPopup(auth, provider);
  const { accessToken, secret } = TwitterAuthProvider.credentialFromResult(user);
}

How to use custom auth domain name?

Add an HTTP proxy handler in your Node.js (Next.js) app that proxies all the HTTP requests starting from /__/ to Firebase xxx.firebaseapp.com (where xxx is Google Cloud project ID). Once this is done, you can set custom domain in the initializeApp(...) method (see above).

NOTE: This is an optional step. You can do it after the rest of the auth flow is configured and working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment