Google One Tap SignIn Popup not showing

Viewed 2112

I was trying to implement Google One Tap SignIn in my project. At the first time after building the project the google one tap prompt will display. But next time onwards if we refresh the page also the prompt is not displaying.

Here is my code snippet.

import { addScript } from 'Util/DOM';

/**
 * Loads One Tap Client Library
 */
const loadOneTapClientLibrary = async() => {
    await addScript('https://accounts.google.com/gsi/client');
}

/**
 * Loads One Tap Javascript API
 * @param {*} resolve 
 */
const loadOneTapJsAPI = (resolve) => {
    window.onload = () => {
        google.accounts.id.initialize({
          client_id: "My client Id",
          callback: data => resolve(data)
        });
        google.accounts.id.prompt();
    }
}

export const loadOneTap = async() => {
    return new Promise( (resolve, reject) => {
        loadOneTapClientLibrary();
        loadOneTapJsAPI(resolve);
    })
}

After page loads i am calling loadOneTap();

2 Answers

To avoid One Tap UI prompting too frequently to end users, if users close the UI by the 'X' button, the One Tap will be disabled for a while. This is the so-called "Exponental Cool Down" feature. More detail at: https://developers.google.com/identity/one-tap/web/guides/features#exponential_cool_down

I believe you triggered this feature during development. To avoid this, use Chrome incognito mode (and restart the browser when necessary).

As noted by Guibin this is the OneTap exponential cool down feature, it can be easily triggered during development when testing auth flow, but also legitimately when the end user clicks the close icon by mistake. On sites where Google login is optional this might seem pragmatic (i.e. the user genuinely wants to dismiss the popup prompt in favor of alternative login methods), however on a site where Google is the sole login identity provider and you are using the Javascript API instead of HTML api then this can manifest as broken functionality - i.e. no login prompt - and you want to avoid telling your users to use incognito or clear cache/cookies at all costs..

You can potentially handle this with some fallback logic..

    window.google.accounts.id.prompt((notification) => {
        if(notification.isNotDisplayed() || !notification.isDisplayed()) {
            // @ts-ignore
            const buttonDiv = window.document.createElement("div")
            buttonDiv.setAttribute("id", "googleLoginBtn")
            document.getElementsByTagName('body')[0].appendChild(buttonDiv);
            // @ts-ignore
            window.google.accounts.id.renderButton(
                document.getElementById("googleLoginBtn"),
                { theme: "outline", size: "large" }  // customization attributes
            );
        }

This renders a button to login that isn't subject the one-tap cool down feature. We're early days into playing with this so there may be other invariants with regards to state you need to consider (e.g. can isNotDisplayed return true when already logged in) - we already observed some oddities where isDisplayed and isNotDisplayed can both be false on the same invocation of the callback.

Extra note: I recall reading the user can disable all one tap features too, so if you're using the javascript API instead HTML api you will need the fallback to SignIn with Google button.

Related