📚 [Docs] Incomplete Expo idToken Guide - Missing Implementation Details for Google/Apple OAuth #2815

Closed
opened 2026-03-13 10:21:53 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @issam-seghir on GitHub (Feb 3, 2026).

Originally assigned to: @bytaesu on GitHub.

📝 Documentation Issue

Affected Page

https://www.better-auth.com/docs/integrations/expo

Problem Description

The Expo integration documentation shows how to use the idToken parameter but doesn't explain how to obtain it, especially for Google and Apple OAuth. This leaves developers confused about:

  1. How to get the idToken from Google/Apple in Expo
  2. Which Google Console OAuth type to use (Web vs Android vs iOS)
  3. What additional Expo packages are needed (if any)
  4. When to use standard flow vs idToken flow

Current Documentation

The docs show this example:

await authClient.signIn.social({
    provider: "google",
    idToken: {
        token: "...", // ID token from provider ❓ How do we get this?
        nonce: "...", // nonce from provider (optional) ❓ Where does this come from?
    },
    callbackURL: "/dashboard"
});

But there's no guidance on:

  • How to obtain the idToken using Expo tools
  • Whether to use expo-auth-session, expo-google-sign-in, or native modules
  • Google Console configuration (which OAuth client type?)
  • iOS/Android-specific setup differences

Expected Documentation

1. Add Clear Comparison Section

## Standard vs IdToken Sign-In

### Standard Flow (Current Default - Recommended for Most)
- Opens browser using `expo-web-browser`
- Better-auth handles OAuth flow entirely
- Simpler setup
- Works with Web OAuth Client ID

### IdToken Flow (Advanced - Native Feel)
- Uses native Google/Apple sign-in sheets
- Requires obtaining idToken manually
- More setup but better UX
- Requires platform-specific OAuth Client IDs

2. Add Complete IdToken Implementation Guide

## Getting IdToken with Expo

### Option 1: Google Sign-In with expo-auth-session

```bash
npx expo install expo-auth-session expo-crypto expo-web-browser
import * as Google from 'expo-auth-session/providers/google';
import * as Crypto from 'expo-crypto';

// Configure Google Auth
const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
  clientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
  iosClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
  androidClientId: 'YOUR_ANDROID_CLIENT_ID.apps.googleusercontent.com',
});

// Handle sign-in
const handleGoogleSignIn = async () => {
  const result = await promptAsync();
  
  if (result.type === 'success' && result.params.id_token) {
    // Send idToken to better-auth
    await authClient.signIn.social({
      provider: "google",
      idToken: { token: result.params.id_token },
      callbackURL: "/dashboard"
    });
  }
};

Option 2: Apple Sign-In with expo-apple-authentication

npx expo install expo-apple-authentication expo-crypto
import * as AppleAuthentication from 'expo-apple-authentication';
import * as Crypto from 'expo-crypto';

const handleAppleSignIn = async () => {
  const nonce = await Crypto.digestStringAsync(
    Crypto.CryptoDigestAlgorithm.SHA256,
    Math.random().toString()
  );
  
  const credential = await AppleAuthentication.signInAsync({
    requestedScopes: [
      AppleAuthentication.AppleAuthenticationScope.EMAIL,
      AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
    ],
  });
  
  if (credential.identityToken) {
    await authClient.signIn.social({
      provider: "apple",
      idToken: { 
        token: credential.identityToken,
        nonce: nonce // Apple requires nonce
      },
      callbackURL: "/dashboard"
    });
  }
};

3. Add Google Console Configuration Guide

## Google Cloud Console Setup for IdToken Flow

### For Web Client (Standard Flow - Current Default)
1. Create **OAuth 2.0 Web Application**
2. Add redirect URI: `https://yourdomain.com/api/auth/callback/google`
3. Use this Client ID in better-auth server config

### For Native IdToken Flow (Advanced)
1. Create **OAuth 2.0 Android Application** 
   - Package name: `com.yourcompany.yourapp`
   - SHA-1 fingerprint: Get from `keytool -list -v -keystore ~/.android/debug.keystore`
2. Create **OAuth 2.0 iOS Application**
   - Bundle ID: `com.yourcompany.yourapp`
3. Use these Client IDs in `expo-auth-session` config
4. Server still uses **Web Client** credentials

When to Use Each Approach?

Criteria Standard Flow IdToken Flow
Ease of Setup Simple ⚠️ Complex
UX Browser popup Native sheet
Performance Slower Faster
Recommended For MVP, Testing Production, iOS
Apple App Store May need review Required

### Impact

This documentation gap causes:
- ❌ Developers thinking they need third-party packages (like `@react-native-google-signin/google-signin`)
- ❌ Confusion about Google Console OAuth client types
- ❌ Uncertainty about when to use idToken vs standard flow
- ❌ Unnecessary complexity in implementation

### Related Issues
- #7025 - Google Sign-In stuck at consent screen (Expo + Express)
- #7049 - Apple sign-in hangs in production builds
- #5034 - State mismatch error with Google OAuth on Expo

### Suggested Fix

Add a new section to the Expo docs:
1. **"Choosing the Right Approach"** - Comparison table
2. **"Standard Flow (Recommended)"** - Current browser-based approach (emphasize this is simpler)
3. **"IdToken Flow (Advanced)"** - Complete implementation guide with `expo-auth-session`
4. **"Google Console Configuration"** - Detailed OAuth client type guide
5. **"Troubleshooting"** - Common issues and solutions

### Additional Context

Many developers (including myself) see the idToken example and assume it's the "proper" way to do OAuth in Expo, when the standard browser-based flow is actually simpler and works perfectly for most use cases. Clarifying this would save hours of confusion.

---

**Would be happy to contribute a PR for this if the maintainers agree with the approach!** 🙌
Originally created by @issam-seghir on GitHub (Feb 3, 2026). Originally assigned to: @bytaesu on GitHub. ## 📝 Documentation Issue ### Affected Page https://www.better-auth.com/docs/integrations/expo ### Problem Description The Expo integration documentation shows **how to use** the `idToken` parameter but doesn't explain **how to obtain** it, especially for Google and Apple OAuth. This leaves developers confused about: 1. **How to get the idToken** from Google/Apple in Expo 2. **Which Google Console OAuth type** to use (Web vs Android vs iOS) 3. **What additional Expo packages** are needed (if any) 4. **When to use standard flow vs idToken flow** ### Current Documentation The docs show this example: ```typescript await authClient.signIn.social({ provider: "google", idToken: { token: "...", // ID token from provider ❓ How do we get this? nonce: "...", // nonce from provider (optional) ❓ Where does this come from? }, callbackURL: "/dashboard" }); ``` But there's no guidance on: - ✅ How to obtain the `idToken` using Expo tools - ✅ Whether to use `expo-auth-session`, `expo-google-sign-in`, or native modules - ✅ Google Console configuration (which OAuth client type?) - ✅ iOS/Android-specific setup differences ### Expected Documentation #### 1. Add Clear Comparison Section ```markdown ## Standard vs IdToken Sign-In ### Standard Flow (Current Default - Recommended for Most) - Opens browser using `expo-web-browser` - Better-auth handles OAuth flow entirely - Simpler setup - Works with Web OAuth Client ID ### IdToken Flow (Advanced - Native Feel) - Uses native Google/Apple sign-in sheets - Requires obtaining idToken manually - More setup but better UX - Requires platform-specific OAuth Client IDs ``` #### 2. Add Complete IdToken Implementation Guide ```markdown ## Getting IdToken with Expo ### Option 1: Google Sign-In with expo-auth-session ```bash npx expo install expo-auth-session expo-crypto expo-web-browser ``` ```typescript import * as Google from 'expo-auth-session/providers/google'; import * as Crypto from 'expo-crypto'; // Configure Google Auth const [request, response, promptAsync] = Google.useIdTokenAuthRequest({ clientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com', iosClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com', androidClientId: 'YOUR_ANDROID_CLIENT_ID.apps.googleusercontent.com', }); // Handle sign-in const handleGoogleSignIn = async () => { const result = await promptAsync(); if (result.type === 'success' && result.params.id_token) { // Send idToken to better-auth await authClient.signIn.social({ provider: "google", idToken: { token: result.params.id_token }, callbackURL: "/dashboard" }); } }; ``` ### Option 2: Apple Sign-In with expo-apple-authentication ```bash npx expo install expo-apple-authentication expo-crypto ``` ```typescript import * as AppleAuthentication from 'expo-apple-authentication'; import * as Crypto from 'expo-crypto'; const handleAppleSignIn = async () => { const nonce = await Crypto.digestStringAsync( Crypto.CryptoDigestAlgorithm.SHA256, Math.random().toString() ); const credential = await AppleAuthentication.signInAsync({ requestedScopes: [ AppleAuthentication.AppleAuthenticationScope.EMAIL, AppleAuthentication.AppleAuthenticationScope.FULL_NAME, ], }); if (credential.identityToken) { await authClient.signIn.social({ provider: "apple", idToken: { token: credential.identityToken, nonce: nonce // Apple requires nonce }, callbackURL: "/dashboard" }); } }; ``` #### 3. Add Google Console Configuration Guide ```markdown ## Google Cloud Console Setup for IdToken Flow ### For Web Client (Standard Flow - Current Default) 1. Create **OAuth 2.0 Web Application** 2. Add redirect URI: `https://yourdomain.com/api/auth/callback/google` 3. Use this Client ID in better-auth server config ### For Native IdToken Flow (Advanced) 1. Create **OAuth 2.0 Android Application** - Package name: `com.yourcompany.yourapp` - SHA-1 fingerprint: Get from `keytool -list -v -keystore ~/.android/debug.keystore` 2. Create **OAuth 2.0 iOS Application** - Bundle ID: `com.yourcompany.yourapp` 3. Use these Client IDs in `expo-auth-session` config 4. Server still uses **Web Client** credentials ``` ### When to Use Each Approach? | Criteria | Standard Flow | IdToken Flow | |----------|--------------|--------------| | **Ease of Setup** | ✅ Simple | ⚠️ Complex | | **UX** | Browser popup | Native sheet | | **Performance** | Slower | Faster | | **Recommended For** | MVP, Testing | Production, iOS | | **Apple App Store** | May need review | ✅ Required | ``` ### Impact This documentation gap causes: - ❌ Developers thinking they need third-party packages (like `@react-native-google-signin/google-signin`) - ❌ Confusion about Google Console OAuth client types - ❌ Uncertainty about when to use idToken vs standard flow - ❌ Unnecessary complexity in implementation ### Related Issues - #7025 - Google Sign-In stuck at consent screen (Expo + Express) - #7049 - Apple sign-in hangs in production builds - #5034 - State mismatch error with Google OAuth on Expo ### Suggested Fix Add a new section to the Expo docs: 1. **"Choosing the Right Approach"** - Comparison table 2. **"Standard Flow (Recommended)"** - Current browser-based approach (emphasize this is simpler) 3. **"IdToken Flow (Advanced)"** - Complete implementation guide with `expo-auth-session` 4. **"Google Console Configuration"** - Detailed OAuth client type guide 5. **"Troubleshooting"** - Common issues and solutions ### Additional Context Many developers (including myself) see the idToken example and assume it's the "proper" way to do OAuth in Expo, when the standard browser-based flow is actually simpler and works perfectly for most use cases. Clarifying this would save hours of confusion. --- **Would be happy to contribute a PR for this if the maintainers agree with the approach!** 🙌
GiteaMirror added the documentation label 2026-03-13 10:21:53 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Feb 3, 2026):

Thank you for sharing that detailed issue regarding the incomplete Expo idToken guide! Currently, it seems that there is no stipulation in the existing documentation on how to obtain the idToken for Google and Apple OAuth within an Expo environment. Therefore, developers may face confusion regarding the necessary Expo packages, Google Console OAuth types, and when to use different flows.

To address this, your suggestions for enhancing documentation are valuable:

  1. Providing clear examples on obtaining the idToken, including configurations for both Google and Apple.
  2. Clarifying which OAuth client types to use in the Google Console.
  3. Including troubleshooting steps and a comparison table to guide developers between standard flow and idToken flow.

It sounds like an excellent enhancement to the documentation! If you wish, I would recommend creating a PR to propose these changes for a clearer and improved experience for developers using Expo with Better Auth.

Feel free to tag @better-auth-agent if you’d like further insights or assistance regarding this matter! Do you have additional aspects you want to propose for the documentation?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

@better-auth-agent[bot] commented on GitHub (Feb 3, 2026): Thank you for sharing that detailed issue regarding the incomplete Expo idToken guide! Currently, it seems that there is no stipulation in the existing documentation on how to obtain the `idToken` for Google and Apple OAuth within an Expo environment. Therefore, developers may face confusion regarding the necessary Expo packages, Google Console OAuth types, and when to use different flows. To address this, your suggestions for enhancing documentation are valuable: 1. Providing clear examples on obtaining the `idToken`, including configurations for both Google and Apple. 2. Clarifying which OAuth client types to use in the Google Console. 3. Including troubleshooting steps and a comparison table to guide developers between standard flow and idToken flow. It sounds like an excellent enhancement to the documentation! If you wish, I would recommend creating a PR to propose these changes for a clearer and improved experience for developers using Expo with Better Auth. Feel free to tag @better-auth-agent if you’d like further insights or assistance regarding this matter! Do you have additional aspects you want to propose for the documentation? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@bytaesu commented on GitHub (Feb 4, 2026):

Thanks @issam-seghir, let me check.
I've set up the Expo app and I am testing it.

@bytaesu commented on GitHub (Feb 4, 2026): Thanks @issam-seghir, let me check. I've set up the Expo app and I am testing it.
Author
Owner

@bytaesu commented on GitHub (Feb 4, 2026):

@issam-seghir, Is there anything else I should look into to make the Expo plugin more solid?

@bytaesu commented on GitHub (Feb 4, 2026): @issam-seghir, Is there anything else I should look into to make the Expo plugin more solid?
Author
Owner

@bytaesu commented on GitHub (Feb 7, 2026):

Hi @issam-seghir,

I’ve updated the docs.

Also, according to the official Expo docs, expo-auth-session/providers/google has been deprecated.

@bytaesu commented on GitHub (Feb 7, 2026): Hi @issam-seghir, I’ve updated the docs. Also, according to the official Expo docs, `expo-auth-session/providers/google` has been deprecated.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2815