Skip to main content

One-tap Google sign in

This is the easiest and recommended way to implement Google Sign In. It is a sign in flow that (on Android) requires very little user interaction, thus increasing conversions. This api is available on Android, iOS and Web (with a little extra work described below).

On Android, it is built on top of the Credential Manager.

On the Web, it covers both the One-tap flow and the Google Sign-In button.

On iOS, the provided API is a wrapper of the iOS Google Sign In SDK, same as the Original Google Sign In. This is so that you can use the same API for both Android and iOS.

tip

The functionality covered in this page is only available to sponsors️. It takes just a few clicks to get access ❤️.

This module is being actively developed, and new features are added regularly. Since the first release in July 2023, there has been more than 1 release per month on average (last updated in April 2024).

Note that on iOS and Android, you can combine the one-tap methods with those one from the Original Google Sign In. To do that, use the One-tap sign in to sign in the user. Then call signInSilently() and then (for example) getCurrentUser() to get the current user's information.

import {
GoogleOneTapSignIn,
statusCodes,
type OneTapUser,
} from '@react-native-google-signin/google-signin';

signIn

signature: (params: OneTapSignInParams) => Promise<OneTapUser>

Attempts to sign in user automatically as explained here. On the web, this call rejects - please read below for web support.

Returns a Promise that resolves with an object containing the user data or rejects in case of error. If there is no user that previously signed in, the promise will reject with NO_SAVED_CREDENTIAL_FOUND error. In that case, you can call createAccount to start a flow to create a new account. You don't need to call signIn as a response to a user action - you can call it when your app starts or when suitable.

UI screenshot
import {
GoogleOneTapSignIn,
statusCodes,
isErrorWithCode,
GoogleSignin
} from '@react-native-google-signin/google-signin';

// Somewhere in your code
const signIn = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleOneTapSignIn.signIn({
webClientId: config.webClientId,
iosClientId: config.iosClientId, // only needed if you're not using the Firebase config file
nonce: 'your_nonce',
});
setState({ userInfo });
} catch (error) {
if (isErrorWithCode(error)) {
switch (error.code) {
case statusCodes.NO_SAVED_CREDENTIAL_FOUND:
// Android only. No saved credential found, try calling `createAccount`
break;
case statusCodes.SIGN_IN_CANCELLED:
// sign in was cancelled
break;
case statusCodes.ONE_TAP_START_FAILED:
// Android and Web only, you probably have hit rate limiting.
// On Android, you can still call `presentExplicitSignIn` in this case.
// On the web, user needs to click the `WebGoogleSigninButton` to sign in.
break;
case statusCodes.PLAY_SERVICES_NOT_AVAILABLE:
// Android-only: play services not available or outdated
break;
default:
// something else happened
}
} else {
// an error that's not related to google sign in occurred
}
}
};

createAccount

signature: (params: OneTapSignInParams) => Promise<OneTapUser>

Starts a flow to sign in with your app for the first time (to create a user account). It offers a list of user accounts to choose from (multiple Google accounts can be logged in on the device).

It should be used if signIn rejects with NO_SAVED_CREDENTIAL_FOUND error, as shown in the code snippet above. You don't need to call createAccount as a response to a user action - you can call it when your app starts or when suitable.

Returns a Promise that resolves with an object containing the user data or rejects in case of error. On the web, this call rejects - please read below for web support.

UI screenshot
await GoogleOneTapSignIn.createAccount({
webClientId: config.webClientId,
nonce: 'your_nonce',
});

presentExplicitSignIn

✨since v14.2.0

signature: (params: OneTapSignInParams) => Promise<OneTapUser>

Presents the sign in dialog explicitly. This is useful when the user has hit rate limiting (ONE_TAP_START_FAILED) and the one-tap flow is thus not available, or if both signIn and createAccount reject with NO_SAVED_CREDENTIAL_FOUND error - which happens (in the unlikely case) when no Google account is present on the device. This will prompt the user to add a Google account.

Call this method only as a reaction to when user taps a "sign in with Google" button.

On the web, this call rejects - please use the Sign in button instead. Read below for web support.

UI screenshot
await GoogleOneTapSignIn.presentExplicitSignIn({
webClientId: config.webClientId,
nonce: 'your_nonce',
});

signOut

signature: (emailOrUniqueId: string) => Promise<null>

Signs out the current user. On the web, you need to provide the id or email of the user. On Android and iOS, this parameter does not have any effect.

Returns a Promise that resolves with null or rejects in case of error.

await GoogleOneTapSignIn.signOut(user.id);

Web support

Providing a unified API for the web is a bit more complex than it may seem. This is because the web experience is quite different from the mobile one, and so are the underlying apis.

The WebGoogleOneTapSignIn.signIn function exists to handle the web-specific logic. Its interface is as close as possible to the native one, allowing to reuse the logic for both success and error handling across all platforms.

To implement web support, follow these steps:

  1. Call WebGoogleOneTapSignIn.signIn upon page load. This will attempt to present the One-tap UI. It also sets up a listener for authentication events and calls the onSuccess callback when the user signs in (either with One-tap flow or the Sign-In button).
warning

You should display the One Tap UI on page load or other window events, instead of it being displayed by a user action (e.g. a button press). Otherwise, you may get a broken UX. Users may not see any UI after a user action, due to globally opt-out, cool-down, or no Google session.

useEffect(() => {
if (Platform.OS === 'web') {
WebGoogleOneTapSignIn.signIn(
{
webClientId: config.webClientId,
},
{
onError: (error: NativeModuleError) => {
// this might be cancellation, one-tap rate limiting, or other errors
},
onSuccess: (userInfo: OneTapUser) => {
// user has signed in, do something with the user info
},
momentListener: (moment) => {
// optional
},
},
);
}
}, []);

Optionally, you can provide a momentListener callback function. The callback is called when important events take place. See reference.

  1. Render the WebGoogleSigninButton component

One-tap UI may not always be available: This happens if user has opted out or when they cancel the dialog several times in a row, entering the cooldown period.

WebGoogleSigninButton serves as a fallback. Tapping it will open the regular Google Sign-In dialog. When user signs in, the onSuccess callback will be called.

info

The reason the WebGoogleOneTapSignIn.signIn api is callback-based rather than promise-based is that it's possible to get into an "error" state (when one-tap is not available) and later get a successful sign in from the button flow. Because of how the Google Sign In for Web SDK is done, modeling this with a promise-based api is not possible.