Chrome扩展中如何用Firebase Google AuthProvider登录?无法使用signInWithPopup
在Chrome扩展中使用Firebase实现谷歌登录(替代
signInWithPopup) Chrome扩展的后台/Service Worker上下文没有window对象,因此依赖浏览器弹窗的signInWithPopup无法使用。以下是两种适配扩展环境的解决方案:
方案一:借助Popup页面使用signInWithRedirect
Popup页面属于有window对象的上下文,可以正常使用Firebase的重定向登录方法。
1. 配置manifest.json
添加必要权限、OAuth2配置和Popup页面声明:
{ "manifest_version": 3, "name": "Firebase谷歌登录扩展", "permissions": ["identity"], "oauth2": { "client_id": "你的Google OAuth客户端ID(需与Firebase后台配置一致)", "scopes": ["email", "profile", "openid"] }, "host_permissions": ["https://*.firebaseio.com/*", "https://identitytoolkit.googleapis.com/*"], "action": { "default_popup": "popup.html" }, "background": { "service_worker": "background.js" } }
2. Popup页面实现登录逻辑
在popup.html中引入Firebase SDK并处理登录流程:
<!DOCTYPE html> <html> <body> <button id="loginBtn">谷歌登录</button> <script type="module"> import { initializeApp } from "https://www.gstatic.com/firebasejs/9.23.0/firebase-app.js"; import { getAuth, signInWithRedirect, getRedirectResult, GoogleAuthProvider } from "https://www.gstatic.com/firebasejs/9.23.0/firebase-auth.js"; // 你的Firebase配置 const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_AUTH_DOMAIN", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_STORAGE_BUCKET", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); const provider = new GoogleAuthProvider(); provider.setCustomParameters({ prompt: 'select_account' }); // 点击按钮触发登录重定向 document.getElementById('loginBtn').addEventListener('click', async () => { await signInWithRedirect(auth, provider); }); // 页面加载时检查重定向结果 window.addEventListener('load', async () => { const result = await getRedirectResult(auth); if (result) { const user = result.user; console.log('登录成功:', user); // 将用户信息同步到后台脚本 chrome.runtime.sendMessage({ type: 'LOGIN_SUCCESS', user: user.toJSON() }); window.close(); } }); </script> </body> </html>
3. 后台脚本接收登录状态
在background.js中处理登录成功后的逻辑:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === 'LOGIN_SUCCESS') { // 保存用户信息到本地存储 chrome.storage.local.set({ currentUser: message.user }); } });
方案二:使用Chrome Identity API + Firebase凭证登录
直接在后台Service Worker中通过Chrome原生API获取授权码,再转换为Firebase凭证完成登录,无需依赖Popup页面。
1. 配置manifest.json
同方案一的配置,额外需将后台脚本声明为模块:
"background": { "service_worker": "background.js", "type": "module" }
2. 后台脚本实现登录逻辑
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.23.0/firebase-app.js"; import { getAuth, GoogleAuthProvider, signInWithCredential } from "https://www.gstatic.com/firebasejs/9.23.0/firebase-auth.js"; const firebaseConfig = { // 你的Firebase配置 }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); async function loginWithGoogle() { try { // 通过Chrome Identity API获取授权令牌 const authToken = await chrome.identity.getAuthToken({ interactive: true }); // 转换为Firebase谷歌登录凭证 const credential = GoogleAuthProvider.credential(null, authToken); // 完成Firebase登录 const userCredential = await signInWithCredential(auth, credential); const user = userCredential.user; console.log('登录成功:', user); chrome.storage.local.set({ currentUser: user.toJSON() }); } catch (error) { console.error('登录失败:', error); // 若令牌无效,清除后重试 if (error.message.includes('invalid_grant')) { chrome.identity.removeCachedAuthToken({ token: error.details.token }, loginWithGoogle); } } } // 监听扩展图标点击触发登录 chrome.action.onClicked.addListener(loginWithGoogle);
关键注意事项
- 确保Google Cloud Console中,OAuth客户端ID已添加Chrome扩展的应用ID作为授权来源,且与Firebase后台的谷歌登录配置使用同一客户端ID。
- 使用Manifest V3时,后台脚本需声明为模块才能引入Firebase的ES模块SDK。
内容的提问来源于stack exchange,提问作者sir-haver
相关产品推荐
相关产品推荐

