You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展v3中GCM/FCM获取推送注册令牌失败求助

问题:Manifest V3 Chrome扩展集成Firebase推送通知无法获取注册令牌

我开发了一款manifest_version为3的Chrome扩展,需集成Firebase实现推送通知功能,已在Firebase控制台创建对应项目,但无法获取发送推送所需的注册令牌。


尝试方案一:使用chrome.gcm API

清单配置

{
  "name": "Notifications",
  "version": "1.0.0.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "popup.html"
  },
  "permissions": [
    "notifications",
    "gcm"
  ],
  "background": {
    "service_worker": "background.js"
  }
}

代码(background.js)

chrome.runtime.onInstalled.addListener((details) => {
    const senderIds = ['****'];

    chrome.gcm.register(senderIds, (registrationId) => {
        if (chrome.runtime.lastError) {
            console.error(`Registration failed: ${chrome.runtime.lastError.message}`);
            return;
        }
        console.log('Registration ID:', registrationId);
    });
});

遇到的问题

在service worker中始终报错:Asynchronous operation is pending


尝试方案二:使用Firebase SDK

清单配置

{
  "manifest_version": 3,
  "name": "FCM Chrome Extension",
  "version": "1.0",
  "permissions": [ "notifications", "storage" ],
  "background": {
    "service_worker": "background.js"
    //"type": "module"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  },
  "web_accessible_resources": [
    {
      "resources": [ "firebase-messaging-sw.js" ],
      "matches": [ "<all_urls>" ]
    }
  ],
  "icons": {
    "48": "images/icon.png"
  }
}

代码(background.js)

importScripts('firebase/firebase-app-compat.js');
importScripts('firebase/firebase-messaging-compat.js');


const firebaseConfig = {
    apiKey: "*",
    authDomain: "*",
    projectId: "*",
    storageBucket: "*",
    messagingSenderId: "*",
    appId: "*",
    measurementId: "*"
};
firebase.initializeApp(firebaseConfig);

console.log('here');
// Retrieve Firebase Messaging object
const messaging = firebase.messaging();
console.log(messaging);

async function fetchToken() {
    try {
        const token = await getToken(messaging, { vapidKey: '*************' }); 
        console.log('FCM Token:', token);
    } catch (error) {
        console.error('Error getting token:', error);
    }
}

fetchToken();

遇到的问题

  • 本地安装Firebase后无法引用内部函数;
  • 使用静态Firebase文件时清单加载失败,添加service worker的module类型后浏览器提示不支持;
  • 尝试通过webpack打包background脚本未解决问题;
  • 最终加载v9.0.0兼容版的Firebase App和Messaging JS文件,虽能获取messaging对象,但getToken函数仍无法正常工作。

解决方案

针对方案一(chrome.gcm API)的修复

Asynchronous operation is pending错误源于Manifest V3 service worker的异步上下文限制,改用Promise封装调用即可解决:

chrome.runtime.onInstalled.addListener(async (details) => {
    const senderIds = ['你的Firebase发件人ID'];
    try {
        const registrationId = await new Promise((resolve, reject) => {
            chrome.gcm.register(senderIds, (id) => {
                const err = chrome.runtime.lastError;
                if (err) reject(err);
                else resolve(id);
            });
        });
        console.log('Registration ID:', registrationId);
        // 将令牌存储到本地备用
        await chrome.storage.local.set({ fcmToken: registrationId });
    } catch (err) {
        console.error(`Registration failed: ${err.message}`);
    }
});

同时确认:

  • 清单中已正确声明gcm权限;
  • Sender ID为Firebase控制台项目设置>云消息传递中的官方发件人ID。

针对方案二(Firebase SDK)的正确配置

1. 清单文件调整

  • 移除web_accessible_resources中对firebase-messaging-sw.js的声明,Manifest V3扩展的service worker无需对外暴露;
  • 修改内容安全策略,允许加载Firebase CDN脚本:
"content_security_policy": {
  "extension_pages": "script-src 'self' https://www.gstatic.com/firebasejs/; object-src 'self'"
}
  • 不要给background service worker设置type: module,Firebase兼容版不支持ES模块导入。

2. 修正Firebase初始化代码

getToken是messaging实例的方法,需正确调用,同时补充权限处理逻辑:

importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js');

const firebaseConfig = {
    // 你的Firebase项目配置
};
firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

// 配置后台消息处理
messaging.onBackgroundMessage((payload) => {
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
        body: payload.notification.body,
        icon: '/images/icon.png'
    };
    self.registration.showNotification(notificationTitle, notificationOptions);
});

async function fetchToken() {
    try {
        // 使用Firebase控制台生成的VAPID公钥
        const token = await messaging.getToken({ vapidKey: '你的VAPID公钥' });
        console.log('FCM Token:', token);
        await chrome.storage.local.set({ fcmToken: token });
    } catch (error) {
        console.error('Error getting token:', error);
        // 处理未授权情况
        if (error.code === 'messaging/permission-blocked' || error.code === 'messaging/permission-default') {
            const permission = await Notification.requestPermission();
            if (permission === 'granted') {
                fetchToken();
            }
        }
    }
}

// 在扩展安装/更新、权限变更时触发令牌获取
chrome.runtime.onInstalled.addListener(fetchToken);
chrome.notifications.onPermissionLevelChanged.addListener((level) => {
    if (level === 'granted') {
        fetchToken();
    }
});

3. 关键注意事项

  • 直接使用Firebase CDN脚本,避免本地文件路径或打包问题;
  • VAPID公钥需与Firebase控制台项目设置>云消息传递>Web配置中生成的密钥对一致;
  • 必须等待用户授予通知权限后,getToken才能成功获取令牌;
  • 利用Chrome的storage API持久化令牌,避免service worker重启后丢失。

内容的提问来源于stack exchange,提问作者Shivani Wadhwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:20:22