# Setting Up Sign-in with Google Using Expo and Supabase

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](https://github.com/react-native-google-signin/google-signin) package by running command:

```bash
npx expo install @react-native-google-signin/google-signin
```

* it will install required package for authentication in Expo
    
* it will update app.json `plugins`
    

### **Step 2: Set Up Your Google Cloud Project**

* Open [Google Cloud Console](https://console.cloud.google.com/) and **create a new project**.
    

#### **Configure the OAuth Consent Screen**

* Navigate to APIs & Services &gt; 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* -&gt; from my experience, this is required for correct iOS setup in development.
    
* Click *Save*.
    

#### **Create Client ID For Web**

* Select *Web application* as the application type.
    
* Enter appropriate *Name.*
    
* Click *Create*. The generated Client ID will be used in your Expo app.
    

---

#### **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:
    

```bash
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](https://supabase.com/docs/guides/auth/social-login/auth-google?queryGroups=platform&platform=react-native). However, for some reason this did not work for me, but at a time you reading this it might work again:

* Run command `eas credentials` from the project root and select *Android* to retrieve the SHA-1 fingerprint.
    
* Find and copy the SHA-1 fingerprint into the appropriate field in the Google Cloud Console.
    

---

#### **Create Client ID For iOS**

* Select *iOS* as the application type.
    
* Enter the *Name* you like
    
* Modify your app.json to add this configuration:
    

```json
"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`
    

### **Step 3: Configure Supabase**

* In your Supabase project, go to Authentication &gt; Sign-in/ Up &gt; section Auth Providers &gt; 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 -&gt; Web Client ID -&gt; 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:

```typescript
// GoogleSignIn.tsx

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:
    

```bash
npx expo prebuild --clean
```

* Now you can run your app on both Android and iOS (either simulator or physical device).
    
* *Make sure you use development build* as this is a requirement of google-signin package.
    

```bash
npx expo run:android
```

On another terminal window:

```shell
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**

* **Error: DEVELOPER\_ERROR**
    
    * This error often indicates a problem with the SHA-1 certificate fingerprint or the OAuth client configuration.
        
    * Try to use options mentioned above.
        
* **Error: Must specify an idToken or an accessToken**
    
    * This usually means the wrong client ID is being used. Ensure you are using the *Web client ID* from the Google Cloud Console.
        

## **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](https://github.com/Dromediansk/mindtaker-rn)

Happy coding! 🚀
