Skip to main content
Shipnative supports Google and Apple Sign-In with both Supabase and Convex backends. The implementation uses different strategies per platform for optimal user experience.

How It Works

ProvideriOS/AndroidWeb
GoogleNative SDK (ID token exchange)OAuth PKCE (browser redirect)
AppleOAuth PKCE via in-app browserOAuth PKCE (browser redirect)
Google on mobile uses @react-native-google-signin/google-signin to get an ID token directly, then exchanges it with Supabase. No browser redirect needed.Apple on mobile uses OAuth PKCE flow with expo-web-browser, which opens an in-app browser for authentication.Web OAuth redirects the browser to the OAuth provider (Google/Apple), then back to /auth/callback where the AuthCallbackScreen handles the token exchange automatically.

Quick Start

import { useSupabaseAuth } from '@/hooks/supabase'

function LoginScreen() {
  const { signInWithGoogle, signInWithApple } = useSupabaseAuth()

  const handleGoogle = async () => {
    const { error } = await signInWithGoogle()
    if (error && error.message !== 'OAuth flow cancelled') {
      alert(error.message)
    }
  }

  const handleApple = async () => {
    const { error } = await signInWithApple()
    if (error && error.message !== 'OAuth flow cancelled') {
      alert(error.message)
    }
  }

  return (
    <View>
      <Button onPress={handleGoogle} title="Continue with Google" />
      <Button onPress={handleApple} title="Continue with Apple" />
    </View>
  )
}

Google Sign-In Setup

1. Create OAuth Credentials

In Google Cloud Console:
  1. Create or select a project
  2. Go to APIs & ServicesOAuth consent screen
    • Configure app name, support email, scopes (openid, email, profile)
  3. Go to APIs & ServicesCredentialsCreate CredentialsOAuth client ID
  4. Create three client IDs:
    • Web application - Copy the Client ID and Client Secret
    • iOS - Use your bundle identifier
    • Android - Use your package name and SHA-1 fingerprint

2. Configure Supabase

In Supabase DashboardAuthenticationProvidersGoogle:
  1. Enable Google provider
  2. Add the Client Secret (from Web client)
  3. Add all Client IDs (Web first, then iOS and Android) separated by commas
  4. Enable Skip nonce check - Required because the React Native Google Sign-In SDK doesn’t support nonce verification

3. Configure Your App

Add to apps/app/.env:
EXPO_PUBLIC_GOOGLE_CLIENT_ID=your-web-client-id.apps.googleusercontent.com
EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID=your-ios-client-id.apps.googleusercontent.com

4. Add Redirect URL

In Supabase DashboardAuthenticationURL ConfigurationRedirect URLs, add:
  • yourappscheme://auth/callback (your app scheme from app.json)
  • http://localhost:19006/auth/callback (local web development)

Rebuild Dev Client

After adding Google Sign-In, rebuild your development client:
npx expo prebuild --clean
yarn ios  # or yarn android

Apple Sign-In Setup

1. Configure App ID

In Apple Developer Portal:
  1. Go to Certificates, Identifiers & ProfilesIdentifiers
  2. Select your App ID (or create one)
  3. Enable Sign In with Apple capability
  4. Save

2. Create Services ID (for OAuth)

  1. Go to Identifiers → Click +
  2. Select Services IDs → Continue
  3. Set identifier (e.g., com.yourcompany.yourapp.signin)
  4. Enable Sign In with Apple
  5. Click Configure:
    • Primary App ID: Select your main app
    • Domains: Add your Supabase domain (e.g., your-project.supabase.co)
    • Return URLs: Add https://your-project.supabase.co/auth/v1/callback
  6. Save

3. Generate Private Key

  1. Go to Keys → Click +
  2. Name it (e.g., “Supabase Auth Key”)
  3. Enable Sign In with Apple
  4. Click Configure → Select your Primary App ID
  5. Register the key
  6. Download the .p8 file (you can only download once!)
  7. Note the Key ID

4. Configure Supabase

In Supabase DashboardAuthenticationProvidersApple:
  1. Enable Apple provider
  2. Enter your Services ID (e.g., com.yourcompany.yourapp.signin)
  3. Enter your Team ID (found in Apple Developer account)
  4. Enter your Key ID
  5. Paste the Private Key content (entire .p8 file including headers)
The private key stays in Supabase Dashboard - it should never be in your app or .env file.

Mobile OAuth Requirements (Convex)

This section applies only to Convex backends. Supabase OAuth works with local development.

Why Mobile OAuth Requires Deployment

When using Convex Auth with OAuth providers (Google, Apple, GitHub), the authentication flow works like this: The OAuth provider (Google/Apple/GitHub) redirects to your Convex site URL (SITE_URL), not directly to your app. This means:
  • SITE_URL must be publicly accessible - OAuth providers cannot redirect to localhost or 127.0.0.1
  • Mobile simulators can’t reach localhost - Even if the OAuth flow started, the final redirect back to your app would fail

Environment Variables Required

Set these in the Convex DashboardSettingsEnvironment Variables:
VariableDescriptionExample
SITE_URLYour Convex deployment URL (must be public)https://your-project.convex.site
AUTH_GOOGLE_IDGoogle OAuth Client ID123456.apps.googleusercontent.com
AUTH_GOOGLE_SECRETGoogle OAuth Client SecretGOCSPX-xxxxx
AUTH_APPLE_IDApple Services IDcom.yourapp.signin
AUTH_APPLE_SECRETApple Client Secret (JWT)eyJhbGc...
AUTH_GITHUB_IDGitHub OAuth App Client IDIv1.abc123
AUTH_GITHUB_SECRETGitHub OAuth App Client Secretghp_xxxxx
You can check your current environment variables with:
npx convex env list

Development Options

If you want to test OAuth with your local Convex backend:
  1. Start your local Convex dev server:
    npx convex dev
    
  2. In another terminal, start ngrok:
    ngrok http 3211
    
    This gives you a public URL like https://abc123.ngrok.io
  3. Set SITE_URL to the ngrok URL:
    npx convex env set SITE_URL "https://abc123.ngrok.io"
    
  4. Update OAuth provider redirect URLs to include your ngrok URL
ngrok URLs change each time you restart. You’ll need to update SITE_URL and your OAuth provider settings each session. For consistent development, use Option 1.
During local development, OAuth works on web but not mobile:
# Run the web version
cd apps/app && yarn web
Web OAuth works because:
  • The browser can follow redirects to localhost
  • Cookies are preserved through the OAuth flow
  • No native app scheme is required
Use this approach to test OAuth logic, then deploy to cloud for mobile testing.

Configure OAuth Provider Redirect URLs

After setting up your Convex deployment, add these redirect URLs to your OAuth providers: Google Cloud Console:
  • Authorized redirect URIs: https://your-project.convex.site/api/auth/callback/google
Apple Developer Portal:
  • Return URLs: https://your-project.convex.site/api/auth/callback/apple
GitHub OAuth App:
  • Authorization callback URL: https://your-project.convex.site/api/auth/callback/github
Your app needs to handle the final redirect from Convex. Ensure your app.json has the correct scheme:
{
  "expo": {
    "scheme": "shipnative"
  }
}
The Convex Auth redirect callback in convex/auth.ts validates these URLs:
callbacks: {
  async redirect({ redirectTo }) {
    // Allow your app's deep link scheme
    if (redirectTo?.startsWith("shipnative://")) {
      return redirectTo
    }
    // Allow Expo development URLs
    if (redirectTo?.startsWith("exp://")) {
      return redirectTo
    }
    // Default fallback for mobile
    return "shipnative://"
  },
}

Web OAuth Setup

Web OAuth works automatically with Shipnative! Just ensure your redirect URLs are configured correctly.
When running on web, OAuth providers redirect the browser directly. Shipnative handles this via the AuthCallbackScreen component which:
  1. Extracts tokens from the URL hash fragment (#access_token=...&refresh_token=...)
  2. Exchanges them for a session with Supabase
  3. Redirects to the authenticated area of your app

Required Configuration

Add these redirect URLs in Supabase DashboardAuthenticationURL ConfigurationRedirect URLs:
# Local development
http://localhost:19006/auth/callback

# Production (replace with your domain)
https://yourapp.com/auth/callback

Google Cloud Console (Web Client)

For Google OAuth on web, ensure your Web application OAuth client has:
  1. Authorized JavaScript origins:
    • http://localhost:19006 (development)
    • https://yourapp.com (production)
  2. Authorized redirect URIs:
    • Your Supabase callback URL: https://your-project.supabase.co/auth/v1/callback

How It Works Technically


Troubleshooting

General Issues

“Google Sign-In is not available on this platform”
  • Ensure @react-native-google-signin/google-signin is installed
  • Rebuild your dev client after adding native modules
“Google ID token not returned”
  • Check that EXPO_PUBLIC_GOOGLE_CLIENT_ID is set correctly
  • Verify the Web Client ID matches what’s in Google Cloud Console
Apple Sign-In button doesn’t appear on Android
  • Apple Sign-In is iOS and Web only. Hide the button on Android:
    {Platform.OS !== 'android' && <AppleSignInButton />}
    
OAuth redirects to wrong place
  • Verify redirect URLs match your app scheme
  • Check backend configuration for correct callback URLs

Supabase-Specific

“Nonce mismatch” errors
  • Enable Skip nonce check in Supabase Google provider settings
Web OAuth shows “Invalid params” error
  • Ensure your redirect URL in Supabase includes /auth/callback
  • Check that detectSessionInUrl: true is set in the Supabase client config (default in Shipnative)
  • Verify your domain is in the allowed redirect URLs in Supabase Dashboard
Web OAuth redirects but doesn’t log in
  • Check browser console for CORS errors
  • Add your domain to Supabase’s allowed origins (Dashboard → Project Settings → API)
  • Ensure tokens aren’t being stripped by your hosting provider’s redirects

Convex-Specific

Mobile OAuth shows “Convex Auth is running” page instead of OAuth provider This happens when SITE_URL is set to localhost or 127.0.0.1. The OAuth flow is trying to use your local Convex server, which mobile devices can’t access. Fix:
# Check current SITE_URL
npx convex env list

# If it shows 127.0.0.1, you need to deploy
npx convex deploy

# Then set SITE_URL to your deployed URL
npx convex env set SITE_URL "https://your-project.convex.site"
OAuth opens WebView but immediately closes or fails
  • Check that expo-web-browser is installed: npx expo install expo-web-browser
  • Verify the OAuth provider credentials are set in Convex Dashboard
  • Check Convex function logs for errors: npx convex logs
“Invalid redirectTo URI” error in Convex logs Your app is sending a redirect URI that isn’t allowed. Update convex/auth.ts:
callbacks: {
  async redirect({ redirectTo }) {
    // Add your allowed schemes
    if (redirectTo?.startsWith("yourappscheme://")) {
      return redirectTo
    }
    if (redirectTo?.startsWith("exp://")) {
      return redirectTo
    }
    return "yourappscheme://"
  },
}
OAuth works on web but not mobile This is expected when using local Convex. See Mobile OAuth Requirements above. Quick checklist:
  1. Is SITE_URL set to a public URL? (not 127.0.0.1 or localhost)
  2. Are OAuth credentials set in Convex Dashboard?
  3. Are OAuth provider redirect URLs configured with your .convex.site domain?
  4. Does your app.json have the correct scheme?
How to debug OAuth flow:
# Watch Convex logs in real-time
npx convex logs --tail

# Check environment variables
npx convex env list
Look for [Convex Auth] log messages that show the redirect flow.

Next Steps