Firebase Google Auth: Cross-Origin-Opener-Policy Error Fix
Problem Statement
When implementing Firebase Google Authentication in Next.js applications, developers often encounter the error: "Cross-Origin-Opener-Policy policy would block the window.closed call." This error appears during the sign-in popup window flow, even when authentication functions correctly and user data is saved in Firebase. The error is browser-related and stems from modern security restrictions around cross-origin interactions between windows.
Recommended Solutions
Switch from Popup to Redirect Authentication
The most effective solution is to avoid using popup-based authentication entirely. Instead, implement the redirect sign-in flow, which bypasses the cross-origin restrictions that trigger the error:
import { getRedirectResult, signInWithRedirect } from 'firebase/auth';
import { useEffect, useState } from 'react';
import { auth, provider } from '../../services/auth';
const Login = () => {
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
getRedirectResult(auth)
.then(response => {
if (!response) return;
// Handle successful authentication
})
.catch(error => {
console.error('Authentication error:', error);
})
.finally(() => setIsLoading(false));
}, []);
const handleLogin = () => {
signInWithRedirect(auth, provider)
.catch(error => console.error('Sign-in redirect failed:', error));
};
return (
<button onClick={handleLogin} disabled={isLoading}>
{isLoading ? 'Loading...' : 'Sign In With Google'}
</button>
);
};
export default Login;
Key implementation notes:
- Use
signInWithRedirect
instead ofsignInWithPopup
- Handle the redirect result with
getRedirectResult
inuseEffect
- Manage loading states to prevent duplicate submissions
- This approach eliminates popup-related errors without compromising functionality
Verify Firebase Configuration
If authentication isn't working, first verify these critical Firebase settings:
Allowed Domains (Firebase Console > Authentication Settings):
- Ensure your domain (e.g.,
localhost
,127.0.0.1
, yourproductiondomain.com) is listed - Development domains:
localhost
and127.0.0.1
must be explicitly added
- Ensure your domain (e.g.,
Google Sign-in Method Must be enabled in:
- Firebase Console > Authentication > Sign-in methods > Google
Correct Firebase Config in your code:
jsconst firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_PROJECT_ID.firebaseapp.com", projectId: "YOUR_PROJECT_ID", appId: "YOUR_APP_ID" };
Configure Security Headers
For Next.js Development
Add unsafe-none
to your Next.js headers configuration:
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'unsafe-none',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin-allow-popups',
},
],
},
];
},
};
For Production (Firebase Hosting)
Update your firebase.json
:
{
"hosting": {
"headers": [
{
"source": "**",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "unsafe-none"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin-allow-popups"
}
]
}
]
}
}
Localhost Workaround
Switch from localhost
to 127.0.0.1
in your development setup:
Update your development script:
json"scripts": { "dev": "next dev -H 127.0.0.1" }
Visit
http://127.0.0.1:3000
instead ofhttp://localhost:3000
Important Notes
- The error often doesn't break functionality - authentication may succeed despite the warning
- Error may appear in Chrome but not Firefox - use Chrome for development testing
- Clear cache after header changes - use incognito mode to ensure updated headers are loaded:bash
chrome --incognito
Why These Solutions Work
Modern browsers enforce strict security rules to prevent cross-origin attacks. The signInWithPopup
method creates security conflicts with these policies. The redirect solution avoids these conflicts entirely, while the header configurations explicitly relax security rules in a controlled manner. The 127.0.0.1 workaround resolves inconsistencies in how browsers treat localhost
.
Production Consideration
For production deployments, always combine:
- Redirect authentication method
- Correct security headers in hosting configuration
- Verified Firebase allowed domains
Security Notes
While unsafe-none
resolves the error:
- Understand security implications before implementing
- Never combine with sensitive operations requiring strong isolation
- Consider CSP policies for robust production security