React Electron项目中Firebase谷歌认证弹窗自动关闭问题求助
问题:React Electron + Firebase谷歌认证弹窗自动关闭
在React Electron项目中使用Firebase谷歌弹窗认证时,弹窗能正常显示但1秒后自动关闭,已添加nativeWindowOpen: true但无效。相关代码如下:
相关代码
index.js
const { app, BrowserWindow, ipcMain } = require("electron"); const path = require("node:path"); let mainWindow; app.on("ready", () => { mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false, nativeWindowOpen: true, webPreferences: { preload: path.join(__dirname, "preload.js"), }, }, }); mainWindow.loadURL(`${app.getAppPath()}\\build\\index.html`); }); // ipcMain.on("LOOOOOOOOOOl", (event, value) => { // console.log(value); // });
FirebaseConfig.js
// Import the functions you need from the SDKs you need import { initializeApp } from "firebase/app"; import { getAnalytics } from "firebase/analytics"; import { getAuth, GoogleAuthProvider } from "firebase/auth"; // Your web app's Firebase configuration // For Firebase JS SDK v7.20.0 and later, measurementId is optional const firebaseConfig = { apiKey: "AIzaSyDCC5_C_XCp5YckJ2z0CkHZ1NyjvF2Wm_E", authDomain: "chatapp-edb8c.firebaseapp.com", projectId: "chatapp-edb8c", storageBucket: "chatapp-edb8c.appspot.com", messagingSenderId: "574617176079", appId: "1:574617176079:web:2eb2ba02d411abf28ebb7a", measurementId: "G-H2FD3WG691", }; // Initialize Firebase const app = initializeApp(firebaseConfig); const analytics = getAnalytics(app); const auth = getAuth(app); const provider = new GoogleAuthProvider(); export { auth, provider };
App.js
import "./App.css"; import { auth, provider } from "./FirebaseConfig"; import { useState } from "react"; import { signInWithPopup } from "firebase/auth"; //electron // const ipcRenderer = window.require("electron").ipcRenderer; // //console.log(var); = ipcRenderer.send("name", var); function App() { //auth firebase const [user, setUser] = useState(null); const handleGoogleSignIn = () => { signInWithPopup(auth, provider) .then((result) => { const user = result.user; setUser(user); }) .catch((err) => { //error }); }; const handleLogout = () => { setUser(null); }; //others // ipcRenderer.send("test", "Hello World!"); return ( <> <div> {user ? ( <> <button onClick={handleLogout}>logout</button> <h2>Welcome {user.displayName}</h2> </> ) : ( <button onClick={handleGoogleSignIn}>sign in with google</button> )} </div> </> ); } export default App;
解决方法
1. 修复Electron窗口配置的嵌套错误
你的index.js中webPreferences嵌套了另一个webPreferences,这会导致配置失效。修改为:
app.on("ready", () => { mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false, nativeWindowOpen: true, preload: path.join(__dirname, "preload.js"), // 将preload移到外层webPreferences下 }, }); mainWindow.loadURL(`${app.getAppPath()}\\build\\index.html`); });
2. 手动处理认证弹窗的创建
在Electron主进程中监听window.open事件,自定义认证窗口的属性,避免被默认行为关闭:
app.on("ready", () => { mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false, nativeWindowOpen: true, preload: path.join(__dirname, "preload.js"), }, }); // 接管window.open行为,创建谷歌认证专用窗口 mainWindow.webContents.setWindowOpenHandler(({ url }) => { const authWindow = new BrowserWindow({ width: 600, height: 600, parent: mainWindow, modal: false, webPreferences: { nodeIntegration: false, contextIsolation: true, }, }); authWindow.loadURL(url); // 窗口关闭时清理资源 authWindow.on("closed", () => { authWindow.destroy(); }); return { action: "deny" }; // 阻止默认窗口打开逻辑 }); mainWindow.loadURL(`${app.getAppPath()}\\build\\index.html`); });
3. 允许第三方Cookie
谷歌认证依赖第三方Cookie,在Electron中需要开启相关设置:
const { session } = require("electron"); app.on("ready", () => { // 允许所有站点的第三方Cookie session.defaultSession.webRequest.onHeadersReceived((details, callback) => { callback({ responseHeaders: { ...details.responseHeaders, "Set-Cookie": [ ...(details.responseHeaders["Set-Cookie"] || []), "SameSite=None; Secure", ], }, }); }); // 其他窗口初始化代码... });
4. 检查Firebase授权域
登录Firebase控制台,在Authentication > 设置 > 授权域中添加以下地址:
http://localhost:3000(开发环境)file://*(生产打包后的本地文件地址)
5. 打印认证错误信息排查问题
修改handleGoogleSignIn的catch块,输出错误详情:
const handleGoogleSignIn = () => { signInWithPopup(auth, provider) .then((result) => { const user = result.user; setUser(user); }) .catch((err) => { console.error("认证失败详情:", err); // 打印错误信息定位问题 }); };
内容的提问来源于stack exchange,提问作者Colin Walker
相关产品推荐
相关产品推荐

