Recently, when building a mobile app and implementing OAuth authentication in Expo and Supabase, I ran into several issues that took me hours to debug. Searching through documentation, forums, and using various AI tools, I found the right solution that worked for both Android and iOS.
Since these problems can be frustrating and time-consuming, I want to share the insights I gathered to help you set up Google Sign-In quickly and avoid common pitfalls.
Step 1: Install Expo Google Sign-In
Install @react-native-google-signin/google-signin package by running command:
npx expo install @react-native-google-signin/google-signin
Step 2: Set Up Your Google Cloud Project
Navigate to APIs & Services > OAuth consent screen.
Choose External for the user type
Fill out the necessary information, such as App name, User support email, and Developer contact information.
Add Test users -> from my experience, this is required for correct iOS setup in development.
Click Save.
Create Client ID For Web
Create Client ID For Android
Select Android as the application type.
Enter your Package Name from your app.json / app.config.js / app.config.ts file (e.g., com.myorg.myapp).
When creating SHA-1 certificate fingerprint there are currently 2 options:
Option 1 - Recommended by Google (worked for me):
- Get the fingerprint certificate by running:
keytool -keystore path-to-debug-or-production-keystore -list -v
where path-to-debug-or-production-keystore is your path to android build: ./android/app/debug.keystore
Hit Enter. For keystore password, leave it empty (used for development)
Find and copy the SHA-1 fingerprint into the appropriate field in the Google Cloud Console.
Click Create.
Option 2: Recommended by Supabase (official way)
This solution is stated in Supabase documentation. However, for some reason this did not work for me, but at a time you reading this it might work again:
Create Client ID For iOS
"expo": {
"ios: {
"bundleIdentifier": "com.<YOUR_USERNAME.APP_SCHEME>"
},
"plugins": [
[
"@react-native-google-signin/google-signin",
{
"iosUrlScheme": "<YOUR_IOS_URL_SCHEME>"
}
]
],
}
In Google Cloud Console, enter Bundle ID**,** which should match with the bundleIdentifier in app.json (if not there, add it)
Copy iOS URL Scheme from Google Cloud Console and paste it app.json under plugins
In your Supabase project, go to Authentication > Sign-in/ Up > section Auth Providers > Google.
Enable Sign in with Google
Copy both OAuth Client ID for web and Android from your Google Cloud console and paste it to the Authorized Client IDs field, separting by comma.
Copy the Client Secret from web client ID and paste it to the field Client Secret (for OAuth)
Enable Skip nonce checks**.** By default, Supabase Auth implements nonce validation during the authentication flow.
From field Callback URL (for OAuth) copy the value and paste the URI in the Google Cloud Console -> Web Client ID -> Authorized redirect URIs. This ensures that your Supabase project is valid for Google authentication.
Step 4: Update Your Expo App
Now the coding part. To implement Google button, you should use the one from @react-native-google-signin/google-signin.
Here is an example:
import {
GoogleSignin,
GoogleSigninButton,
} from "@react-native-google-signin/google-signin";
import React from "react";
import { supabase } from "@/utils/supabase";
import { router } from "expo-router";
import { useAuthStore } from "@/store/auth.store";
GoogleSignin.configure({
webClientId: process.env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID,
iosClientId: process.env.EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID,
});
const GoogleSignIn = () => {
const { authLoading, setAuthLoading, setUser } = useAuthStore();
const handleSignIn = async () => {
try {
setAuthLoading(true);
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
if (userInfo.data?.idToken) {
const { data, error } = await supabase.auth.signInWithIdToken({
provider: "google",
token: userInfo.data.idToken,
});
if (error) {
console.error(error);
}
const user = data?.user;
if (user) {
setUser({
id: user.id,
email: user.email || "",
name: user.user_metadata.name,
fullName: user.user_metadata.full_name,
avatarUrl: user.user_metadata.picture,
});
router.replace("/");
}
} else {
throw new Error("no ID token present!");
}
} catch (error: unknown) {
console.error(error);
} finally {
setAuthLoading(false);
}
};
return (
<GoogleSigninButton
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={handleSignIn}
disabled={authLoading}
/>
);
};
export default GoogleSignIn;
Be careful when configuring GoogleSignIn.configure:
in webClientId paste client ID from Web Client ID, NOT Android Client ID.
in iosClientId paste client ID from iOS.
Step 4: Build and Test
- Build your app using expo prebuild:
npx expo prebuild --clean
npx expo run:android
On another terminal window:
npx expo run:ios
- Go to your device and click the Google Sign-In button and verify that you can sign in successfully.
Common Issues and Troubleshooting
Conclusion
Setting up Google Sign-In in an Expo project with Supabase can be tricky. The most common pitfalls involve incorrect OAuth credentials, missing SHA-1 fingerprints, or using the wrong client ID.
By following this guide, you should be able to set up authentication smoothly and avoid wasting hours debugging.
If you run into issues or need further assistance, feel free to reach out to me. You can also check out the full source code in my GitHub repository for a complete working example:
👉 GitHub Repository
Happy coding! 🚀