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
Errorthat has acodefromCredentialErrorand the native error text inmessage. Every code, its causes and an errors-by-method table are in Errors. Every rejection of the library has acode; narrow it withisCredentialError. - 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, andoauthSignIn. Android has no lock, except thatappleSignInandoauthSignInshare the browser: starting one resolves the pending one asCANCELLED. - 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.
| Method | iOS warns for | Android warns for |
|---|---|---|
googleSignIn | authorizedAccounts, autoSelectEnabled, mode, offlineAccess | hint |
googleSilentSignIn | authorizedAccounts, autoSelectEnabled, mode, offlineAccess, hint, scopes, nonce | hint, mode |
hybridSignIn | any client id, and every option except nonce | hint, mode, scopes, offlineAccess, hostedDomain, serverClientId |
appleSignIn | nonce, state | |
createPassKey, getPassKey | preferImmediatelyAvailableCredentials: false | mediation: 'autofill' |
oauthSignIn | prefersEphemeralSession | |
passwordSignIn | always (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:
GIDClientIDin Info.plist, thenCLIENT_IDof the FirebaseGoogleService-Info.plistbundled in the app.serverClientIddefaults toGIDServerClientIDfrom Info.plist. - Android: the
com.oauthessentials.GOOGLE_WEB_CLIENT_ID<meta-data>of<application>in AndroidManifest.xml, then thedefault_web_client_idstring generated by the Firebasegoogle-servicesGradle plugin. - When none is found, rejects with
CONFIGURATION_ERROR(themessagelists these sources).
- iOS:
- 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.webClientIdis the defaultserverClientId(idToken audience andserverAuthCode). - Android uses
webClientId.
- iOS uses
- 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
- Resolves the client ids (see Google client ids) and rejects with
CONFIGURATION_ERRORwhen there is no iOS client id or its URL scheme is not in Info.plist. - Configures GoogleSignIn with the iOS client id, plus
serverClientIdandhostedDomain. - Rejects with
BROWSER_UNAVAILABLEif Guided Access is on. - If the app is not active, waits up to 2 seconds for it to become active, then rejects with
BROWSER_UNAVAILABLE. - Finds the top most view controller attached to a window (rejects with
NO_ACTIVITY_ERRORwhen there is none) and rejects withBROWSER_UNAVAILABLEwhen its window is not in the foreground (e.g. Control Center is open). - Calls
GIDSignIn.signIn(withPresenting:hint:additionalScopes:nonce:), which opens anASWebAuthenticationSession. "Unable to open Safari." errors are reported asBROWSER_UNAVAILABLE.
Android
- Rejects with
CONFIGURATION_ERRORwithout a web client id (passed or in the app config),NOT_SUPPORTED_ERRORwithout Google Play Services andNO_ACTIVITY_ERRORwithout an activity. mode: 'bottomSheet'(default): Credential ManagerGetGoogleIdOptionwithauthorizedAccounts,autoSelectEnabledandnonce. When there is no credential (no account on the device, or the sheet is in cooldown after being dismissed) andauthorizedAccountsis not set, it falls back to the button flow.mode: 'button':GetSignInWithGoogleOptionwithnonceandhostedDomain, the full "Sign in with Google" flow (lets the user add an account).- When
scopesorofflineAccessare set, calls the Authorization API for that account withscopes(oropenid,email,profile),hostedDomainand, withofflineAccess,requestOfflineAccess(serverClientId ?? webClientId). It may show a consent screen; declining it resolvesCANCELLED.
| iOS | Android | |
|---|---|---|
| Resolves | GOOGLE_ID, CANCELLED | GOOGLE_ID, CANCELLED |
| Rejects | CONFIGURATION_ERROR, BROWSER_UNAVAILABLE, NO_ACTIVITY_ERROR, SIMULTANEOUS_CALL_ERROR, INVALID_RESULT_ERROR | CONFIGURATION_ERROR, NOT_SUPPORTED_ERROR, NO_ACTIVITY_ERROR, NO_SIGN_IN_AVAILABLE, INVALID_RESULT_ERROR |
| Events | success / failure | success / failure |
Options per platform
| Option | iOS | Android |
|---|---|---|
nonce | ✅ | ✅ |
hint | ✅ | ignored |
hostedDomain | ✅ | button flow and authorization only |
scopes | requested during sign in | requested in the authorization step |
offlineAccess | no effect (serverAuthCode comes when serverClientId is set) | returns serverAuthCode |
serverClientId | idToken audience + serverAuthCode | client id of the serverAuthCode |
mode, authorizedAccounts, autoSelectEnabled | ignored | ✅ |
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 callsGIDSignIn.restorePreviousSignIn, which never shows UI and refreshes the tokens.hint,scopes,nonceandofflineAccessare ignored, andserverAuthCodeis alwaysnull. - Android:
GetGoogleIdOptionwithfilterByAuthorizedAccountsandautoSelectEnabledforced 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).modeis ignored. Whenscopes/offlineAccessare set, authorization is requested without UI. If consent would be needed, the result hasaccessToken: nullinstead 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, sogoogleSilentSignInrejects 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:
ASAuthorizationPasswordProviderrequest. On iOS 16+ it only offers passwords already on the device. ResolvesPASSWORD, orCANCELLEDwhen the user dismisses it or there is no saved password. Rejects withINVALID_RESULT_ERRORon other errors andSIMULTANEOUS_CALL_ERROR. - Android: Credential Manager
GetPasswordOption. ResolvesPASSWORD, orCANCELLEDwhen the user dismisses it or there is no saved password. Rejects withNOT_SUPPORTED_ERRORwithout Play Services,NO_ACTIVITY_ERRORandINVALID_RESULT_ERRORon 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);
}
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 thetextContentType(username,password,newPassword) props of your inputs so iOS offers to save it. - Android: Credential Manager
createCredential(CreatePasswordRequest), which shows the save prompt. Resolvestruewhen saved andfalseon any error, including the user declining. Rejects withNOT_SUPPORTED_ERRORwithout Play Services andNO_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_IDorCANCELLED. Rejects withINVALID_RESULT_ERRORandSIMULTANEOUS_CALL_ERROR. - Apple only sends
emailandfullNameon the first authorization. This function keeps the first result of eachuserin memory (lost when the app is killed) and fills emptyemail/fullNamefrom it. Store them on your backend. idTokenandauthorizationCodearenullwhen Apple does not return them.stateisoptions.stateechoed 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_IDwith the redirecturl,scheme,host,pathandquery. - Resolves
CANCELLEDwhen the user closes the tab or anoauthSignInstarts. - Rejects with
INVALID_RESULT_ERROR(missing/invalid url),NO_ACTIVITY_ERRORandBROWSER_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.
clientIdis ignored, Google is not included, and onlyoptions.nonceis used (for Apple ID). On iOS 16+ only credentials already on the device are offered. ResolvesAPPLE_IDorPASSWORD, orCANCELLEDwhen the user dismisses it or nothing is available. Rejects withINVALID_RESULT_ERRORandSIMULTANEOUS_CALL_ERROR. - Android: Credential Manager with Google ID (
GetGoogleIdOptionwith the web client id,authorizedAccounts,autoSelectEnabled,nonce) + saved passwords. Apple is not included, andmode,hint,scopes,offlineAccess,hostedDomainandserverClientIdare ignored. ResolvesGOOGLE_IDorPASSWORD, orCANCELLED. Rejects withCONFIGURATION_ERROR(no web client id passed or in the app config),NOT_SUPPORTED_ERROR(no Play Services),NO_ACTIVITY_ERROR,NO_SIGN_IN_AVAILABLEandINVALID_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,attestationand, on iOS 17.4+,excludeCredentials. Other fields are ignored.datais a JSON string withid,rawId,typeandresponse.clientDataJSON/attestationObject(base64url). Rejects withNOT_SUPPORTED_ERRORbelow iOS 16 andSIMULTANEOUS_CALL_ERROR. - Android 9+: Credential Manager
CreatePublicKeyCredentialRequestwith the whole JSON andpreferImmediatelyAvailableCredentials.datais the registration response JSON from Credential Manager. Rejects withNOT_SUPPORTED_ERRORbelow Android 9 andNO_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,allowCredentialsanduserVerification.mediation: 'modal'(default) shows a sheet that only offers passkeys on the device, with no "other device" QR option, so it resolvesCANCELLEDwhen there is none. Rejects withSIMULTANEOUS_CALL_ERRORwhile a passkey call is pending.mediation: 'autofill'shows no sheet. It waits until the user picks a passkey in the QuickType bar of atextContentType="username"field. Any latercreatePassKey/getPassKeycall, orcancelPassKeyAutoFill(), resolves it asCANCELLED.datais a JSON string withid,rawId,typeandresponse.clientDataJSON/authenticatorData/signature/userHandle(base64url). Rejects withNOT_SUPPORTED_ERRORbelow iOS 16.
- Android 9+: Credential Manager
GetPublicKeyCredentialOptionwith the whole JSON andpreferImmediatelyAvailableCredentials.mediationis ignored.datais the authentication response JSON from Credential Manager. Rejects withNOT_SUPPORTED_ERRORbelow Android 9,NO_ACTIVITY_ERRORandNO_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:
- Generates a random
stateand a PKCE S256 verifier/challenge on the native side (32 and 16 random bytes, base64url). - Builds
authorizationEndpoint?response_type=code&client_id=…&redirect_uri=…&state=…, plusscope(space separated) andcode_challenge+code_challenge_method=S256whenusePKCEis notfalse.additionalParametersare added last and may overridescope;response_type,client_id,redirect_uri,state,code_challengeandcode_challenge_methodare ignored there (with a warning in development), since the library checks or reuses them. - Opens it in
ASWebAuthenticationSessionon iOS, with theredirectUrischeme as callback andprefersEphemeralSession. On Android it opens a Custom Tab (http/https urls only), where the redirect must reach the library'sCustomTabsActivity: useOAUTH_REDIRECT_URIor add an intent filter for your uri. - Reads the redirect query and fragment parameters and checks that
statematches. error=access_deniedresolvesCANCELLED. Any othererror, or a missingcode, rejects.- When
tokenEndpointis set, it POSTsgrant_type=authorization_code,code,client_id,redirect_uriandcode_verifierasapplication/x-www-form-urlencodedand returns the JSON response intokens. No client secret is sent and theid_tokenis 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 (messageis itserror_description/error) or a non JSON response.NETWORK_ERROR: the token request failed (offline, DNS, TLS...).CONFIGURATION_ERROR:redirectUrihas 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) andSIMULTANEOUS_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_ERRORbelow 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.
| Constant | iOS | Android |
|---|---|---|
GOOGLE_PLAY_SERVICES_SUPPORTED | false | Play Services installed and up to date |
GOOGLE_ID_SUPPORTED | true | same as GOOGLE_PLAY_SERVICES_SUPPORTED |
PASSWORD_SUPPORTED | true | same as GOOGLE_PLAY_SERVICES_SUPPORTED |
APPLE_ID_SUPPORTED | true | true (web flow) |
HYBRID_SUPPORTED | true | same as GOOGLE_PLAY_SERVICES_SUPPORTED |
PASSKEYS_SUPPORTED | iOS 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;
}