Short answer
Browsers only allow a popup that opens right after a click. If your code awaits something (loading config, a network call) before signInWithPopup, the click may no longer count, and the browser can block the popup. Call signInWithPopup first thing in the click handler, or use signInWithRedirect, following Firebase’s redirect best practices.
Why the popup fails, and the fix
01
Work runs before signInWithPopup
“Popup windows must be opened in direct response to user input, and a separate user gesture event is required for each Window.open() call.” MDN, Window.open()
A click gives the page a short window in which it may open a popup. Awaiting anything first, such as fetching settings or checking a database, can use up that window, so the browser blocks the popup. Do that work before the click, and make signInWithPopup the first call in the handler.
02
A security header cuts the popup off from your page
“It also means that any object opened by your document in a new BCG can't access it using window.opener.” MDN, Cross-Origin-Opener-Policy
Some security templates add Cross-Origin-Opener-Policy: same-origin. With it, a page your app opens from another origin can’t reach your page through window.opener. Neither MDN nor Firebase links this header to Firebase errors, so this is our own check: when the popup opens but the app reports popup-closed-by-user, we look for this header and try same-origin-allow-popups. popup-closed-by-user can also simply mean the person closed the window.
03
Mobile browsers: Firebase prefers redirect
“The redirect method is preferred on mobile devices.” Firebase, Authenticate using Google with JavaScript
Firebase prefers redirect on mobile. Redirect has its own catch: browsers that block third-party storage break it unless you apply one of the setup options on Firebase’s redirect best practices page. For apps not hosted on Firebase, one of those options is to go back to signInWithPopup().
Checked against the vendor’s docs on : MDN: Window.open(); MDN: Transient activation; MDN: Cross-Origin-Opener-Policy; Firebase docs: Authenticate using Google with JavaScript; Firebase docs: Best practices for signInWithRedirect.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.See scope and start
Related: Firebase auth/unauthorized-domain · Google OAuth redirect_uri_mismatch · Google Sign-In fails on Android (error 10) · Unexpected Gemini API charges on Firebase