reactjsreact-nativeexpoexpo-go

Expo Google OAuth: makeRedirectUri returns exp:// instead of auth.expo.io, and manual redirect URI causes "Something went wrong" error


I'm implementing Google OAuth in my Expo app using expo-auth-session and Firebase, but I'm facing two interconnected issues:

  1. makeRedirectUri({ useProxy: true }) returns exp://192.168.1.48:8081 instead of https://auth.expo.io/@username/slug
  2. When I manually hardcode the redirect URI to https://auth.expo.io/@myname/mobile, Google authentication succeeds, but I get redirected to a blank auth.expo.io screen with the error:

    "Something went wrong trying to finish signing in. Please close this screen to go back to the app."

Current Code

import { useEffect } from "react";
import * as WebBrowser from "expo-web-browser";
import {
  makeRedirectUri,
  useAuthRequest,
  ResponseType,
} from "expo-auth-session";
import { GoogleAuthProvider, signInWithCredential } from "firebase/auth";
import { auth } from "../services/firebase";
import Constants from "expo-constants";

WebBrowser.maybeCompleteAuthSession();

const discovery = {
  authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
  tokenEndpoint: "https://oauth2.googleapis.com/token",
};

export function useGoogleAuth() {
  // This returns exp://192.168.1.48:8081 instead of https://auth.expo.io
  const redirectUri = makeRedirectUri({
    useProxy: true,
  });

  const [request, response, promptAsync] = useAuthRequest(
    {
      clientId: Constants.expoConfig?.extra?.GOOGLE_WEB_CLIENT_ID,
      scopes: ["openid", "profile", "email"],
      redirectUri: redirectUri,
    },
    discovery,
  );

  useEffect(() => {
    console.log("==================");
    console.log(
      "Client ID:",
      Constants.expoConfig?.extra?.GOOGLE_WEB_CLIENT_ID,
    );
    console.log("Redirect URI:", redirectUri);
    console.log("==================");
    console.log("Auth request:", request);
    console.log("Auth response:", response);
  }, [response]);

  useEffect(() => {
    if (response?.type === "success") {
      const { id_token } = response.params;
      console.log("Got ID token, signing in to Firebase...");
      const credential = GoogleAuthProvider.credential(id_token);
      signInWithCredential(auth, credential)
        .then((userCredential) => {
          console.log("Signed in:", userCredential.user.email);
        })
        .catch((error) => {
          console.error("Firebase sign-in error:", error);
        });
    } else if (response?.type === "error") {
      console.error(" Auth error:", response.error);
      console.error("Error params:", response.params);
    } else if (response?.type === "cancel") {
      console.log("User cancelled authentication");
    }
  }, [response]);

  return {
    request,
    promptAsync,
  };
}

app.json Configuration

{
  "expo": {
    "name": "Seated",
    "slug": "mobile",
    "owner": "myname",
    "scheme": "mobile",
    "extra": {
      "GOOGLE_WEB_CLIENT_ID": "xxxxx.apps.googleusercontent.com"
    }
  }
}

Debug Output

LOG  Owner: myname
LOG  Slug: mobile
LOG  Scheme: mobile
LOG  makeRedirectUri (useProxy: true): exp://192.168.1.48:8081
LOG  makeRedirectUri (native): exp://192.168.1.48:8081
LOG  makeRedirectUri (preferNative): exp://192.168.1.48:8081

Google Cloud Console Configuration

In my Google Cloud Console OAuth 2.0 Client (Web application), I have tried adding:

What I've Tried

  1. Using makeRedirectUri({ useProxy: true }): Always returns exp:// URL instead of https://auth.expo.io
  2. Hardcoding the redirect URI:
    const redirectUri = `https://auth.expo.io/@samjoshuadud/mobile`;
    
    This passes Google's authorization, but then fails to redirect back to my app
  3. Verified I'm logged into Expo: expo whoami returns my username
  4. Verified owner and slug are set correctly in app.json
  5. Added WebBrowser.maybeCompleteAuthSession() at the top of the file

Questions

  1. Why is makeRedirectUri({ useProxy: true }) not returning the https://auth.expo.io URL even though owner and slug are properly configured?
  2. How can I properly configure the redirect URI so that after Google authentication, the app receives the auth response instead of showing the "Something went wrong" error page?
  3. Is the scheme: "mobile" in app.json interfering with the Expo proxy redirect behavior?

Solution

  • Implementing Google-OAuth with expo-auth-session is quite problematic and will lead you to all sorts of redirect URI and authorization errors (I have had the same issue before). Instead, I recommend using @react-native-google-signin/google-signin which is also what Expo Documentation recommends as well for a more streamlined and issue-free experience. However, for this method you will require a dev build (EAS build recommended) and some setup (on the documentation page). Also, use Firebase if you can it can be very useful!