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 solve the issue, but haven't found the solution yet.
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.