Skip to main content

Google ID Sign-In

Platform Support​

iOS​

  • Uses the GoogleSignIn SDK, which opens the Google page in an ASWebAuthenticationSession
  • Presented from the top most view controller; waits up to 2 seconds for the app to become active
  • No Google Play Services dependency
  • GOOGLE_ID_SUPPORTED is always true
  • Uses iosClientId (or GIDClientID from Info.plist, then CLIENT_ID of GoogleService-Info.plist) and webClientId as the default serverClientId (or GIDServerClientID from Info.plist)
  • Needs the reversed iOS client id as a URL scheme in Info.plist; without it the call rejects with CONFIGURATION_ERROR

Android​

  • Minimum: Android 7.0 (API 24, the library minSdk)
  • Uses Credential Manager (GetGoogleIdOption bottom sheet or GetSignInWithGoogleOption button flow) and, for scopes/offlineAccess, the Authorization API
  • Requires Google Play Services: without them it rejects with NOT_SUPPORTED_ERROR. GOOGLE_ID_SUPPORTED equals GOOGLE_PLAY_SERVICES_SUPPORTED
  • Uses webClientId (or the com.oauthessentials.GOOGLE_WEB_CLIENT_ID manifest meta-data, then the Firebase default_web_client_id string); without any the call rejects with CONFIGURATION_ERROR
  • Supports additional options: mode, authorizedAccounts and autoSelectEnabled

Methods​

googleSignIn(clientId?: GoogleClientId | null, options?: GoogleSignInOptions)​

Performs Google ID sign-in on Android and iOS platforms. Also callable as googleSignIn() and googleSignIn(options) when the client ids are in the app config (the simplest setup).

Parameters​

NameTypeDescription
clientIdstring | { iosClientId?: string; webClientId?: string } (optional)Your Google client ids. Omit it to read them from the app config. See Client ids.
optionsGoogleSignInOptions (optional)Optional configuration for Google Sign-In. See GoogleSignInOptions for details.

Client ids​

From the app config (recommended). Call googleSignIn() or googleSignIn(options) and the native side reads the ids from the app (the Expo config plugin writes them, from its options or the Firebase files):

  • iOS: GIDClientID in Info.plist, then CLIENT_ID of the Firebase GoogleService-Info.plist bundled in the app. serverClientId (idToken audience and serverAuthCode) defaults to GIDServerClientID.
  • Android: the com.oauthessentials.GOOGLE_WEB_CLIENT_ID meta-data in AndroidManifest.xml, then the default_web_client_id string generated by the Firebase google-services Gradle plugin.

See Installation for the native snippets. With no id anywhere, the call rejects with CONFIGURATION_ERROR (the message lists the sources).

In code. Pass { iosClientId, webClientId } (type GoogleClientIds), all from the same Google Cloud project. A passed id wins over the config, and a missing one is read from it:

  • iOS uses iosClientId. webClientId becomes the default serverClientId.
  • Android uses webClientId. The Android client id is never passed: it only has to exist with your package name and SHA-1 fingerprints.

An object with iosClientId or webClientId is the client ids; any other object is the options. A string still works and is used as is: it must be the iOS client id on iOS and the web client id on Android. Pass null to give options explicitly without client ids.

GoogleSignInOptions​

type GoogleSignInOptions = {
authorizedAccounts?: boolean; // Android only: Filter to authorized accounts
autoSelectEnabled?: boolean; // Android only: Enable auto-selection
mode?: 'bottomSheet' | 'button'; // Android only: UI flow (default 'bottomSheet')
nonce?: string; // Embedded as-is in the idToken (replay protection)
hint?: string; // iOS only: Email to preselect
hostedDomain?: string; // Workspace domain (Android: button flow and authorization only)
scopes?: string[]; // Extra OAuth scopes
offlineAccess?: boolean; // Android only: returns serverAuthCode
serverClientId?: string; // iOS: idToken audience + serverAuthCode (default webClientId). Android: serverAuthCode client id
};
  • mode: 'button' should be used when the user taps a "Sign in with Google" button. bottomSheet falls back to it automatically when no credential is available, unless authorizedAccounts is set.
  • scopes and offlineAccess trigger an extra consent step on Android (Authorization API). Declining it resolves CANCELLED.
  • On iOS scopes are requested during sign in, and accessToken/grantedScopes are always returned. serverAuthCode is returned whenever serverClientId is set (offlineAccess has no effect).

Options that have no effect on the current platform log a console.warn in development. See Methods for the exact per-platform behavior.

Returns​

Promise<GoogleIdCredentialResult | CancelledCredentialResult>

The promise resolves to:

GoogleIdCredentialResult:

{
type: CredentialsType.GOOGLE_ID;
data: {
id: string; // iOS: Google user id (sub). Android: account email
idToken: string; // JWT ID token for backend verification
displayName: string; // Full name
givenName: string; // First name
familyName: string; // Last name
email?: string; // Email
profilePictureUri?: string | null; // Profile picture URL
phoneNumber?: string | null; // Android only
accessToken?: string | null; // iOS: always. Android: when `scopes`/`offlineAccess` is set
serverAuthCode?: string | null; // iOS: when `serverClientId` is set. Android: when `offlineAccess` is set
grantedScopes?: string[] | null; // Same as accessToken
};
}

CancelledCredentialResult:

{
type: CredentialsType.CANCELLED;
data: null; // User cancelled the sign-in flow
}

Error Codes​

The method may throw errors with the following codes:

Error CodeDescriptionPlatform
CONFIGURATION_ERRORNo client id passed nor found in the app config (see Client ids), or the iOS URL scheme is missing from Info.plist (the message has the exact scheme)Both
NOT_SUPPORTED_ERRORGoogle Play Services not available or outdatedAndroid only
NO_ACTIVITY_ERRORNo activity / view controller to present fromBoth
NO_SIGN_IN_AVAILABLENo Google account available for the requested filter (iOS: googleSilentSignIn only)Both
BROWSER_UNAVAILABLEThe sign-in page could not be opened (app not active within 2 s, Guided Access, Safari restricted)iOS only
SIMULTANEOUS_CALL_ERRORgoogleSignIn/googleSilentSignIn is still pendingiOS only
INVALID_RESULT_ERRORThe provider failed or returned an unexpected resultBoth

Important Notes​

  • Check GOOGLE_ID_SUPPORTED before calling this method (on Android it is false without Play Services)
  • The idToken should be sent to your backend for verification
  • Options mode, authorizedAccounts and autoSelectEnabled only work on Android
  • User can cancel the flow, resulting in CancelledCredentialResult
  • Use idToken's sub claim (verified on your backend) as the user id: data.id differs between platforms

Example Usage (TypeScript)​

import {
googleSignIn,
isCredentialError,
GOOGLE_ID_SUPPORTED,
CredentialsType,
CredentialError,
} from 'react-native-oauth-essentials';

const GOOGLE_CLIENT_IDS = {
iosClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
};

async function signInWithGoogle(): Promise<void> {
// Android: false without Google Play Services
if (!GOOGLE_ID_SUPPORTED) {
console.log('Google sign-in is not available on this device.');
return;
}

try {
const credential = await googleSignIn(GOOGLE_CLIENT_IDS, {
authorizedAccounts: true, // Android only
autoSelectEnabled: false, // Android only
});

if (credential.type === CredentialsType.GOOGLE_ID) {
console.log('Signed in with Google:');
console.log('ID Token:', credential.data.idToken);
console.log('User ID:', credential.data.id);
console.log('Name:', credential.data.displayName);
console.log('Email:', credential.data.email);

// Send idToken to your backend for verification
await authenticateWithBackend(credential.data.idToken);
} else if (credential.type === CredentialsType.CANCELLED) {
console.log('User cancelled Google sign-in');
}
} catch (error) {
if (isCredentialError(error, CredentialError.CONFIGURATION_ERROR)) {
console.error('Setup problem:', error.message); // e.g. the iOS URL scheme to add
} else if (isCredentialError(error, CredentialError.NOT_SUPPORTED_ERROR)) {
console.error('Please install or update Google Play Services');
} else if (isCredentialError(error, CredentialError.BROWSER_UNAVAILABLE)) {
console.error('Could not open the Google page, try again');
} else if (isCredentialError(error, CredentialError.NO_ACTIVITY_ERROR)) {
console.error('Activity context not available');
} else {
console.error('Google sign-in failed:', error);
}
}
}

googleSilentSignIn(clientId?: GoogleClientId | null, options?: GoogleSignInOptions)​

Restores a previous Google sign in. Takes the same optional clientId as googleSignIn (googleSilentSignIn() reads the ids from the app config). Resolves GoogleIdCredentialResult and rejects with NO_SIGN_IN_AVAILABLE when there is nothing to restore (plus the googleSignIn errors).

  • iOS: restorePreviousSignIn, never shows UI and refreshes the tokens. hint, scopes, nonce and offlineAccess are ignored and serverAuthCode is null.
  • Android: bottom sheet filtered to accounts that already signed in to the app, with auto select on: no UI when there is a single one, otherwise the sheet is shown (dismissing it resolves CANCELLED). mode and hint are ignored. Authorization for scopes/offlineAccess is only requested without UI; when consent would be needed accessToken is null.
const credential = await googleSilentSignIn(); // or googleSilentSignIn(GOOGLE_CLIENT_IDS)

signOut()​

Clears the Google session on iOS (so googleSilentSignIn rejects afterwards) and the Credential Manager state on Android (turns off auto select until the user picks an account again). Resolves true, does not emit events.

await signOut();

Setup Requirements​

  1. Configure OAuth 2.0 in Google Cloud Console (see the Google OAuth setup guide), all in the same project:

    • Web client id: your webClientId
    • Android client id: package name + SHA-1 of every signing key (including Play App Signing). Never passed in code
    • iOS client id: bundle id. Your iosClientId
  2. Native configuration - iOS: add the reversed iOS client id as a URL scheme in Info.plist (1234-abcd.apps.googleusercontent.com becomes com.googleusercontent.apps.1234-abcd), plus GIDClientID / GIDServerClientID to call googleSignIn() without ids. Android: the com.oauthessentials.GOOGLE_WEB_CLIENT_ID meta-data (or Firebase google-services.json) to call it without ids. See Installation, or use the Expo config plugin google option, which writes all of it

  3. Backend Token Verification (Recommended):

Best Practices​

  1. Always verify the ID token on your backend - Don't trust client-side tokens
  2. Check platform support constants before calling the method
  3. Handle cancellation gracefully - Users may change their mind
  4. Provide fallback options - Not all devices have Google Play Services
  5. Keep the ids in the app config (or pass { iosClientId, webClientId }) - Never the Android Client ID from Google Cloud Console