reactjsfirebase-authentication

How to listen error event of Firebase Auth Provider immediately?


When using Firebase Auth provider with signInWithPopup, when the user clicks to close the popup, error.code === 'auth/popup-closed-by-user' is returned. But not immediately, there is some delay. Why? I want to listen to the error event when the user closes the popup immediately.

I provide my code using signInWithPopup of Firebase Auth provider.

export const signInWithSocial = async (type: string) => {
    let provider: any;

    if (type === SocialLoginType.google) {
        provider = googleProvider;
    } else if (type === SocialLoginType.facebook) {
        provider = facebookProvider;
        provider.setCustomParameters({
            display: 'popup'
        });
    } else if (type === SocialLoginType.twitter) {
        provider = twitterProvider;
        provider.setCustomParameters({
            lang: 'en'
        });
    } else if (type === SocialLoginType.apple) {
        provider = appleProvider;
        provider.addScope('email');
        provider.addScope('name');
    }

    auth.signInWithPopup(provider)
        .then(async (result) => {
            const { user } = result;
            const idToken = await user.getIdToken();

            window.localStorage.setItem('idToken', idToken);
            window.dispatchEvent(new Event('storage'));
        })
        .catch((error) => {
            console.log('--- Login Error: ' + JSON.stringify(error) + ' ---\n');

            const customEvent = new CustomEvent('stopSocialProcess');
            window.dispatchEvent(customEvent);
        });
};

I've researched the Firebase documentation and related articles to try to resolve this issue, but haven't found a solution yet.


Solution

  • This delay is caused by an intentional 8 second delay in the Firebase.js SDK, see this pull request. The reason for this was to support blocking functions and fix an issue with Firefox.

    There's currently no setting to change AUTH_EVENT reliably back to 2000 ms.

    A hacky fix however has been given by GitHub user hacktisch which overrules all 8 second timeouts to a 2 second timeout:

    (function() {
      const originalSetTimeout = window.setTimeout;
      window.setTimeout = function(fn, delay, ...args) {
        // Check if the delay matches Firebase's _Timeout.AUTH_EVENT
        if (delay === 8000) {
          delay = 2000; 
        }
        return originalSetTimeout(fn, delay, ...args);
      };
    })();
    

    (it goes without saying that you should confirm you have no other 8 sec timeouts in your code)

    See this GitHub issue for more context.