Skip to main content

Methods

Exact reference of every function exported by react-native-oauth-essentials: what it calls on each platform, what it resolves, what it rejects with and which events it emits.

Conventions​

  • Cancellation resolves. When the user dismisses the UI, methods resolve { type: 'CANCELLED', data: null } instead of rejecting (exceptions are noted per method).
  • Errors reject with an Error that has a code from CredentialError and the native error text in message. Every code, its causes and an errors-by-method table are in Errors. Every rejection of the library has a code; narrow it with isCredentialError.
  • Events. Credential methods also report their result through addCredentialSuccessListener / addCredentialFailureListener (see Events).
  • Simultaneous calls (iOS). Calling a method again while its previous call is pending rejects the new call with SIMULTANEOUS_CALL_ERROR (the pending one keeps going). The locks are: googleSignIn + googleSilentSignIn, getPassword, hybridSignIn, appleSignIn, createPassKey + getPassKey, and oauthSignIn. Android has no lock, except that appleSignIn and oauthSignIn share the browser: starting one resolves the pending one as CANCELLED.
  • Threading (iOS). Every method runs on the main thread.
  • Development warnings. See Ignored options.
  • Missing native module. Importing the library throws when its native code is not in the app binary: in Expo Go it says the library does not work there (use a development build), otherwise it asks to rebuild the app after installing (pod install + native build; reloading Metro is not enough) and to enable the New Architecture.

Ignored options​

In development (__DEV__), passing an option that has no effect on the current platform logs a console.warn once per method and option: [react-native-oauth-essentials] <method>: "<option>" is ignored on <Platform>. Release builds never warn.

MethodiOS warns forAndroid warns for
googleSignInauthorizedAccounts, autoSelectEnabled, mode, offlineAccesshint
googleSilentSignInauthorizedAccounts, autoSelectEnabled, mode, offlineAccess, hint, scopes, noncehint, mode
hybridSignInany client id, and every option except noncehint, mode, scopes, offlineAccess, hostedDomain, serverClientId
appleSignInnonce, state
createPassKey, getPassKeypreferImmediatelyAvailableCredentials: falsemediation: 'autofill'
oauthSignInprefersEphemeralSession
passwordSignInalways (it does nothing on iOS)

Google client ids​

googleSignIn, googleSilentSignIn and hybridSignIn take an optional clientId of type GoogleClientId: { iosClientId?, webClientId? } or a string. Each accepts (clientId?, options?) and (options): an object with iosClientId or webClientId is the client id, any other object is the options (null also means "no client id").

  • Omitted (recommended when the ids are in the app config): googleSignIn() / googleSignIn(options). The native side reads them from the app:
    • iOS: GIDClientID in Info.plist, then CLIENT_ID of the Firebase GoogleService-Info.plist bundled in the app. serverClientId defaults to GIDServerClientID from Info.plist.
    • Android: the com.oauthessentials.GOOGLE_WEB_CLIENT_ID <meta-data> of <application> in AndroidManifest.xml, then the default_web_client_id string generated by the Firebase google-services Gradle plugin.
    • When none is found, rejects with CONFIGURATION_ERROR (the message lists these sources).
  • Object: { iosClientId: IOS_CLIENT_ID, webClientId: WEB_CLIENT_ID }. A passed id wins over the config; a missing one is read from it as above.
    • iOS uses iosClientId. webClientId is the default serverClientId (idToken audience and serverAuthCode).
    • Android uses webClientId.
  • String: used as is on both platforms, so it must be the iOS client id on iOS and the web client id on Android.

The Expo plugin writes Info.plist and the Android meta-data from its options or the Firebase files.

On iOS, before calling GoogleSignIn, the library checks that a client id exists and that the reversed client id (1234-abcd.apps.googleusercontent.com becomes com.googleusercontent.apps.1234-abcd) is in CFBundleURLTypes > CFBundleURLSchemes. Otherwise it rejects with CONFIGURATION_ERROR (the message has the exact scheme to add) instead of letting GoogleSignIn crash the app. See Installation or the Expo plugin.

Google​

googleSignIn(clientId?, options?)​

Shows the Google sign in UI and resolves with the signed in account.

iOS

  1. Resolves the client ids (see Google client ids) and rejects with CONFIGURATION_ERROR when there is no iOS client id or its URL scheme is not in Info.plist.
  2. Configures GoogleSignIn with the iOS client id, plus serverClientId and hostedDomain.
  3. Rejects with BROWSER_UNAVAILABLE if Guided Access is on.
  4. If the app is not active, waits up to 2 seconds for it to become active, then rejects with BROWSER_UNAVAILABLE.
  5. Finds the top most view controller attached to a window (rejects with NO_ACTIVITY_ERROR when there is none) and rejects with BROWSER_UNAVAILABLE when its window is not in the foreground (e.g. Control Center is open).
  6. Calls GIDSignIn.signIn(withPresenting:hint:additionalScopes:nonce:), which opens an ASWebAuthenticationSession. "Unable to open Safari." errors are reported as BROWSER_UNAVAILABLE.

Android

  1. Rejects with CONFIGURATION_ERROR without a web client id (passed or in the app config), NOT_SUPPORTED_ERROR without Google Play Services and NO_ACTIVITY_ERROR without an activity.
  2. mode: 'bottomSheet' (default): Credential Manager GetGoogleIdOption with authorizedAccounts, autoSelectEnabled and nonce. When there is no credential (no account on the device, or the sheet is in cooldown after being dismissed) and authorizedAccounts is not set, it falls back to the button flow.
  3. mode: 'button': GetSignInWithGoogleOption with nonce and hostedDomain, the full "Sign in with Google" flow (lets the user add an account).
  4. When scopes or offlineAccess are set, calls the Authorization API for that account with scopes (or openid, email, profile), hostedDomain and, with offlineAccess, requestOfflineAccess(serverClientId ?? webClientId). It may show a consent screen; declining it resolves CANCELLED.
iOSAndroid
ResolvesGOOGLE_ID, CANCELLEDGOOGLE_ID, CANCELLED
RejectsCONFIGURATION_ERROR, BROWSER_UNAVAILABLE, NO_ACTIVITY_ERROR, SIMULTANEOUS_CALL_ERROR, INVALID_RESULT_ERRORCONFIGURATION_ERROR, NOT_SUPPORTED_ERROR, NO_ACTIVITY_ERROR, NO_SIGN_IN_AVAILABLE, INVALID_RESULT_ERROR
Eventssuccess / failuresuccess / failure

Options per platform

OptioniOSAndroid
nonce✅✅
hint✅ignored
hostedDomain✅button flow and authorization only
scopesrequested during sign inrequested in the authorization step
offlineAccessno effect (serverAuthCode comes when serverClientId is set)returns serverAuthCode
serverClientIdidToken audience + serverAuthCodeclient id of the serverAuthCode
mode, authorizedAccounts, autoSelectEnabledignored✅

Result fields that differ: id is the Google user id (sub) on iOS and the account email on Android. accessToken and grantedScopes are always set on iOS, and are null on Android unless scopes or offlineAccess were requested. phoneNumber is Android only.

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

try {
// ids from the app config; or googleSignIn({ iosClientId, webClientId }, { mode: 'button', nonce })
const result = await googleSignIn({ mode: 'button', nonce });
if (result.type === CredentialsType.GOOGLE_ID) {
await api.signInWithGoogle(result.data.idToken);
}
} catch (e) {
if (isCredentialError(e, CredentialError.BROWSER_UNAVAILABLE)) {
// ask the user to try again with the app in foreground
} else if (isCredentialError(e, CredentialError.CONFIGURATION_ERROR)) {
console.error(e.message); // setup bug, e.g. the missing iOS URL scheme
}
}

googleSilentSignIn(clientId?, options?)​

Restores a previous Google sign in.

  • iOS: if there is no stored session, rejects with NO_SIGN_IN_AVAILABLE. Otherwise it calls GIDSignIn.restorePreviousSignIn, which never shows UI and refreshes the tokens. hint, scopes, nonce and offlineAccess are ignored, and serverAuthCode is always null.
  • Android: GetGoogleIdOption with filterByAuthorizedAccounts and autoSelectEnabled forced on, so it signs in without UI when a single account already signed in to the app (it shows the sheet when there are several). mode is ignored. When scopes/offlineAccess are set, authorization is requested without UI. If consent would be needed, the result has accessToken: null instead of being cancelled.

Resolves GOOGLE_ID or CANCELLED (user dismissed the Android sheet). Rejects with NO_SIGN_IN_AVAILABLE when there is nothing to restore, plus the same errors as googleSignIn (including CONFIGURATION_ERROR). Takes the same optional clientId. Emits success / failure events.

try {
const result = await googleSilentSignIn();
} catch (e) {
if (isCredentialError(e, CredentialError.NO_SIGN_IN_AVAILABLE)) showSignInScreen();
}

signOut()​

  • iOS: GIDSignIn.signOut(): removes the Google session, so googleSilentSignIn rejects afterwards. It does not touch Apple ID or passwords.
  • Android: Credential Manager clearCredentialState. It turns off auto select for every provider until the user picks an account again.

Resolves true. Rejects with INVALID_RESULT_ERROR on Android when clearing fails. Does not emit events.

Passwords​

getPassword()​

Shows the app's saved passwords and resolves with the one the user picks.

  • iOS: ASAuthorizationPasswordProvider request. On iOS 16+ it only offers passwords already on the device. Resolves PASSWORD, or CANCELLED when the user dismisses it or there is no saved password. Rejects with INVALID_RESULT_ERROR on other errors and SIMULTANEOUS_CALL_ERROR.
  • Android: Credential Manager GetPasswordOption. Resolves PASSWORD, or CANCELLED when the user dismisses it or there is no saved password. Rejects with NOT_SUPPORTED_ERROR without Play Services, NO_ACTIVITY_ERROR and INVALID_RESULT_ERROR on other errors.

Returns Promise<PasswordCredentialResult | CancelledCredentialResult>: it never resolves false. Emits the success event when it resolves (including CANCELLED) and the failure event when it rejects.

const result = await getPassword();
if (result.type === CredentialsType.PASSWORD) {
await api.signIn(result.data.username, result.data.password);
}
Migrating to 1.1

Before 1.1, Android resolved false when there was no password or on errors. Replace if (!result) / result === false checks with result.type === CredentialsType.CANCELLED.

passwordSignIn(username, password)​

Saves a username/password in the platform password manager. It does not authenticate the user against anything.

  • iOS: does nothing and resolves false. iOS has no API to save a password without an associated domain. Use the textContentType (username, password, newPassword) props of your inputs so iOS offers to save it.
  • Android: Credential Manager createCredential(CreatePasswordRequest), which shows the save prompt. Resolves true when saved and false on any error, including the user declining. Rejects with NOT_SUPPORTED_ERROR without Play Services and NO_ACTIVITY_ERROR.

Does not emit events, except the failure event for the Android rejections.

Apple​

appleSignIn(androidWebUrl?, options?)​

iOS: native Sign in with Apple sheet (ASAuthorizationAppleIDProvider) requesting fullName and email, with options.nonce and options.state. androidWebUrl is ignored.

  • Resolves APPLE_ID or CANCELLED. Rejects with INVALID_RESULT_ERROR and SIMULTANEOUS_CALL_ERROR.
  • Apple only sends email and fullName on the first authorization. This function keeps the first result of each user in memory (lost when the app is killed) and fills empty email/fullName from it. Store them on your backend.
  • idToken and authorizationCode are null when Apple does not return them. state is options.state echoed back.

Android: opens androidWebUrl in a Custom Tab. options is ignored, so put the nonce/state in your url. Your backend runs the Apple web flow and must redirect to <applicationId>://oauth/callback, the uri the library's CustomTabsActivity handles.

  • Resolves WEB_APPLE_ID with the redirect url, scheme, host, path and query.
  • Resolves CANCELLED when the user closes the tab or an oauthSignIn starts.
  • Rejects with INVALID_RESULT_ERROR (missing/invalid url), NO_ACTIVITY_ERROR and BROWSER_UNAVAILABLE (no browser installed).

Emits success / failure events on both platforms.

const result = await appleSignIn('https://api.example.com/auth/apple', { nonce: sha256(rawNonce) });

getAppleIdCredentialState(userId)​

Asks Apple, without UI, whether userId (the user of APPLE_ID) is still signed in to the app (ASAuthorizationAppleIDProvider.getCredentialState). Call it on app start and sign the user out when it is not AUTHORIZED.

Resolves AUTHORIZED, REVOKED, TRANSFERRED or NOT_FOUND. Rejects with INVALID_RESULT_ERROR when the check fails. On Android it always rejects with NOT_SUPPORTED_ERROR. Does not emit events.

if ((await getAppleIdCredentialState(storedUserId)) !== AppleIdCredentialState.AUTHORIZED) {
signOutLocally();
}

Hybrid​

hybridSignIn(clientId?, options?)​

Shows a single picker with the credentials the user already has, meant for app start. The providers differ per platform:

  • iOS: Apple ID + saved passwords. clientId is ignored, Google is not included, and only options.nonce is used (for Apple ID). On iOS 16+ only credentials already on the device are offered. Resolves APPLE_ID or PASSWORD, or CANCELLED when the user dismisses it or nothing is available. Rejects with INVALID_RESULT_ERROR and SIMULTANEOUS_CALL_ERROR.
  • Android: Credential Manager with Google ID (GetGoogleIdOption with the web client id, authorizedAccounts, autoSelectEnabled, nonce) + saved passwords. Apple is not included, and mode, hint, scopes, offlineAccess, hostedDomain and serverClientId are ignored. Resolves GOOGLE_ID or PASSWORD, or CANCELLED. Rejects with CONFIGURATION_ERROR (no web client id passed or in the app config), NOT_SUPPORTED_ERROR (no Play Services), NO_ACTIVITY_ERROR, NO_SIGN_IN_AVAILABLE and INVALID_RESULT_ERROR.

Emits success / failure events.

const result = await hybridSignIn({ authorizedAccounts: true }); // or hybridSignIn({ webClientId }, options)

Passkeys​

createPassKey({ requestJson, preferImmediatelyAvailableCredentials? })​

Registers a passkey from your server's WebAuthn PublicKeyCredentialCreationOptions JSON.

  • iOS 16+: platform passkey registration. It reads challenge, rp.id, user.id, user.name, authenticatorSelection.userVerification, attestation and, on iOS 17.4+, excludeCredentials. Other fields are ignored. data is a JSON string with id, rawId, type and response.clientDataJSON / attestationObject (base64url). Rejects with NOT_SUPPORTED_ERROR below iOS 16 and SIMULTANEOUS_CALL_ERROR.
  • Android 9+: Credential Manager CreatePublicKeyCredentialRequest with the whole JSON and preferImmediatelyAvailableCredentials. data is the registration response JSON from Credential Manager. Rejects with NOT_SUPPORTED_ERROR below Android 9 and NO_ACTIVITY_ERROR.

Resolves PASSKEY or CANCELLED. Rejects with INVALID_RESULT_ERROR for a missing/invalid requestJson and other errors. Emits success / failure events. Send data to your server to verify it.

getPassKey({ requestJson, preferImmediatelyAvailableCredentials?, mediation? })​

Signs in with a passkey from your server's WebAuthn PublicKeyCredentialRequestOptions JSON.

  • iOS 16+: platform passkey assertion. It reads challenge, rpId, allowCredentials and userVerification.
    • mediation: 'modal' (default) shows a sheet that only offers passkeys on the device, with no "other device" QR option, so it resolves CANCELLED when there is none. Rejects with SIMULTANEOUS_CALL_ERROR while a passkey call is pending.
    • mediation: 'autofill' shows no sheet. It waits until the user picks a passkey in the QuickType bar of a textContentType="username" field. Any later createPassKey/getPassKey call, or cancelPassKeyAutoFill(), resolves it as CANCELLED.
    • data is a JSON string with id, rawId, type and response.clientDataJSON / authenticatorData / signature / userHandle (base64url). Rejects with NOT_SUPPORTED_ERROR below iOS 16.
  • Android 9+: Credential Manager GetPublicKeyCredentialOption with the whole JSON and preferImmediatelyAvailableCredentials. mediation is ignored. data is the authentication response JSON from Credential Manager. Rejects with NOT_SUPPORTED_ERROR below Android 9, NO_ACTIVITY_ERROR and NO_SIGN_IN_AVAILABLE (no passkey).

Resolves PASSKEY or CANCELLED. Rejects with INVALID_RESULT_ERROR for a missing/invalid requestJson and other errors. Emits success / failure events.

cancelPassKeyAutoFill()​

Cancels a pending getPassKey({ mediation: 'autofill' }), which then resolves (and emits) CANCELLED. Call it when the sign in screen unmounts.

Resolves true when a pending AutoFill request was cancelled and false when there was none. Always resolves false on Android and below iOS 16.

Generic OAuth / OpenID Connect​

oauthSignIn(options)​

Signs in with any OAuth 2.0 / OpenID Connect provider using the authorization code flow:

  1. Generates a random state and a PKCE S256 verifier/challenge on the native side (32 and 16 random bytes, base64url).
  2. Builds authorizationEndpoint?response_type=code&client_id=…&redirect_uri=…&state=…, plus scope (space separated) and code_challenge + code_challenge_method=S256 when usePKCE is not false. additionalParameters are added last and may override scope; response_type, client_id, redirect_uri, state, code_challenge and code_challenge_method are ignored there (with a warning in development), since the library checks or reuses them.
  3. Opens it in ASWebAuthenticationSession on iOS, with the redirectUri scheme as callback and prefersEphemeralSession. On Android it opens a Custom Tab (http/https urls only), where the redirect must reach the library's CustomTabsActivity: use OAUTH_REDIRECT_URI or add an intent filter for your uri.
  4. Reads the redirect query and fragment parameters and checks that state matches.
  5. error=access_denied resolves CANCELLED. Any other error, or a missing code, rejects.
  6. When tokenEndpoint is set, it POSTs grant_type=authorization_code, code, client_id, redirect_uri and code_verifier as application/x-www-form-urlencoded and returns the JSON response in tokens. No client secret is sent and the id_token is not validated.

Resolves OAUTH with code, state, redirectUri, codeVerifier (null without PKCE), params (all redirect params) and tokens (null without tokenEndpoint). Resolves CANCELLED when the user closes the browser, the provider returns access_denied or, on Android, an appleSignIn starts.

Rejects with:

  • INVALID_RESULT_ERROR: state mismatch, provider error, no code, the token endpoint returned non 2xx (message is its error_description/error) or a non JSON response.
  • NETWORK_ERROR: the token request failed (offline, DNS, TLS...).
  • CONFIGURATION_ERROR: redirectUri has no scheme.
  • BROWSER_UNAVAILABLE: iOS Guided Access, app not active within 2 seconds, its window not in the foreground, or the session could not start; Android with no browser installed.
  • NO_ACTIVITY_ERROR (no activity on Android, no view controller in a window on iOS) and SIMULTANEOUS_CALL_ERROR (iOS).

Does not emit events, not even for rejections. See OAuth Sign-In.

Events​

See also the Events guide.

addCredentialSuccessListener(listener)​

Called with the same { type, data } the promise resolves with, including CANCELLED. It fires for googleSignIn, googleSilentSignIn, getPassword, appleSignIn, hybridSignIn, createPassKey and getPassKey.

addCredentialFailureListener(listener)​

Called with { code, message } when one of those methods rejects (including CONFIGURATION_ERROR). These rejections are not emitted:

  • SIMULTANEOUS_CALL_ERROR;
  • iOS passkey NOT_SUPPORTED_ERROR below iOS 16;
  • iOS missing requestJson.

addAppleIdCredentialRevokedListener(listener)​

Called when iOS posts ASAuthorizationAppleIDProvider.credentialRevokedNotification, meaning the user stopped using Apple ID with the app while it is running. Never called on Android.

signOut, passwordSignIn (iOS), getAppleIdCredentialState, cancelPassKeyAutoFill and oauthSignIn do not emit events.

const success = addCredentialSuccessListener((event) => analytics.track('sign_in', { type: event.type }));
const failure = addCredentialFailureListener((event) => analytics.track('sign_in_error', { code: event.code }));
const revoked = addAppleIdCredentialRevokedListener(() => signOutLocally());

// later
success.remove();
failure.remove();
revoked.remove();

Constants​

Read once when the module loads.

ConstantiOSAndroid
GOOGLE_PLAY_SERVICES_SUPPORTEDfalsePlay Services installed and up to date
GOOGLE_ID_SUPPORTEDtruesame as GOOGLE_PLAY_SERVICES_SUPPORTED
PASSWORD_SUPPORTEDtruesame as GOOGLE_PLAY_SERVICES_SUPPORTED
APPLE_ID_SUPPORTEDtruetrue (web flow)
HYBRID_SUPPORTEDtruesame as GOOGLE_PLAY_SERVICES_SUPPORTED
PASSKEYS_SUPPORTEDiOS 16+Android 9+ (API 28)
OAUTH_REDIRECT_URI<bundle id, lowercased>://oauth/callback<applicationId>://oauth/callback

Errors​

isCredentialError(error, code?)​

Type guard for a catch: returns true when error is an object whose code is a CredentialError value (and equals code when given), narrowing it to OauthEssentialsError (Error & { code }). It never throws and does not check instanceof Error.

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

try {
await googleSignIn();
} catch (e) {
if (isCredentialError(e, CredentialError.CONFIGURATION_ERROR)) console.error(e.message);
else if (isCredentialError(e)) report(e.code);
else throw e;
}