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

Manifest V3 Chrome扩展在Edge中FCM通知重复显示问题求助

Edge浏览器FCM推送重复显示通知问题解决指南

问题说明

基于Manifest V3开发的Chrome扩展,通过FCM API V1实现消息推送,在Chrome中运行正常,但在MS Edge中触发推送时,会同时弹出系统默认通知(“此网站已在后台更新”)和自定义通知,需要仅保留自定义通知。

提供的代码文件

manifest.json

{
    "name": "Staines Memorial College Notifications",
    "version": "1.0.1",
    "description": "Recieve notifications for Staines Memorial College and the Diary App.",
    "manifest_version": 3,
    "author": "Braydan Mengel - Staines Memorial College",
    "action": {
        "default_popup": "Ext_Status.html",
        "default_title": "Staines Memorial College Notifications Extension"
    },
    "permissions": [
        "notifications",
        "background",
        "storage"
    ],
    "background": {
        "service_worker": "background.js",
        "type": "module"
    },
    "icons": {
        "48": "Images/ExtensionIcon48.png",
        "128": "Images/ExtensionIcon128.png"
    }
}

background.js

import { getMessaging } from "./firebase/firebase-messaging-sw.js";
import { getToken } from "./firebase/firebase-messaging.js";
import { initializeApp } from "./firebase/firebase-app.js";

//init firebase
initializeApp({
    apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
});

//global variables
var UserID;

//chrome local storage
chrome.storage.local.get(["userData"]).then((result) => {
    if (result.userData === undefined) {
        chrome.tabs.create({ url: chrome.runtime.getURL("Ext_Login.html") });
    } else {
        UserID = result.userData.uuid;
        setTimeout(() => {
            RegTopic();
        }, 1000)
    }
});

async function RegTopic() {
    //get the gcm device token and send it to the server
    const token = await getToken(getMessaging(), {
        serviceWorkerRegistration: self.registration
    });

    const details = {
        "userid": UserID,
        "token": token
    };

    fetch("https://example.com/ins/tokens/fcm/regToken", {
        method: "POST",
        headers: {
            "Content-Type": "application/json; charset=UTF-8"
        },
        body: JSON.stringify(details)
    })
        .then(response => response.json())
        .then(data => {
            if (data.message === 'Registered') {
                console.log('Registered token successfully!');
            }
        })
        .catch(error => {
            setTimeout(() => {
                RegTopic();
            }, 5000)
            console.error("Error:", error);
        });
}

//when a message is received
self.addEventListener('push', function (event) {
    const Message = event.data.json();

    if (Message.data.link === "NONE") {
        // No link found
        if (Message.data.priority === "0") {
            // Priority is set to 0 meaning Normal
            const showNotification = self.registration.showNotification(`Staines Notifications - ${Message.data.title}`, {
                icon: "../Images/Notify.png",
                body: Message.data.body,
                requireInteraction: false,
                data: {
                    notificationid: Message.data.notificationid,
                    linkOpening: Message.data.link
                }
            });

            event.waitUntil(showNotification);
        } else if (Message.priority === "1") {
            // Priority is set to 1 meaning Important
            const showNotification = self.registration.showNotification(`Staines Notifications - ${Message.data.title}`, {
                icon: "../Images/Notify.png",
                body: Message.data.body,
                requireInteraction: true,
                data: {
                    notificationid: Message.data.notificationid,
                    linkOpening: Message.data.link
                }
            });

            event.waitUntil(showNotification);
        }
    } else {
        // Link is included; priority is set to 1 meaning Important by default
        const showNotification = self.registration.showNotification(`Staines Notifications - ${Message.data.title}`, {
            icon: "../Images/Notify.png",
            body: Message.data.body,
            requireInteraction: true,
            data: {
                notificationid: Message.data.notificationid,
                linkOpening: Message.data.link
            }
        });

        event.waitUntil(showNotification);
    }
});

//Login message handler
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.type === 'login') {
        UserID = message.data.userid;
        const response = { status: 'success' };
        sendResponse(response);

        RegTopic();
    }
});

// Notification handlers
self.addEventListener('notificationclick', function (event) {
    const clickedNotification = event.notification;
    const linkOpening = clickedNotification.data.linkOpening;

    if (linkOpening !== 'NONE') {
        event.waitUntil(
            clients.openWindow(linkOpening)
        );
    }
});

self.addEventListener('notificationclose', function (event) {
    const clickedNotification = event.notification;
    const linkOpening = clickedNotification.data.linkOpening;

    if (linkOpening !== 'NONE') {
        event.waitUntil(
            clients.openWindow(linkOpening)
        );
    }
});

补充信息

  • 使用Firebase 9.0.0版本的核心脚本(firebase-app.js、firebase-messaging.js、firebase-messaging-sw.js),已随扩展打包
  • 扩展目录包含根目录核心文件、Images资源文件夹、firebase脚本文件夹及登录/状态页面

解决方法

Edge出现默认通知的核心原因是:当FCM推送仅包含data字段时,Edge会自动生成默认通知,而Chrome不会触发该行为。以下两种方案均可解决:

方案一:客户端拦截默认行为

在Service Worker的push事件开头添加event.preventDefault(),阻止浏览器生成默认通知,代码修改如下:

self.addEventListener('push', function (event) {
    // 阻止浏览器默认通知逻辑
    event.preventDefault();
    
    const Message = event.data.json();

    // 后续自定义通知逻辑保持不变
    if (Message.data.link === "NONE") {
        // ... 原代码
    } else {
        // ... 原代码
    }
});

此方法无需修改服务器端推送逻辑,直接在客户端拦截,操作简单。

方案二:服务器端调整推送消息结构

在发送FCM消息时,添加webpush.fcm_options.link字段,设置为扩展内的页面地址(比如状态页),Edge识别到是扩展内部地址后,不会弹出默认通知。示例推送请求体:

{
  "message": {
    "token": "目标设备的FCM Token",
    "data": {
      "title": "自定义标题",
      "body": "自定义内容",
      "link": "跳转链接",
      "priority": "1",
      "notificationid": "通知ID"
    },
    "webpush": {
      "fcm_options": {
        "link": "chrome-extension://你的扩展ID/Ext_Status.html"
      }
    }
  }
}

注:替换你的扩展ID为实际的扩展ID,该地址不影响自定义跳转逻辑,仅用于屏蔽Edge默认通知。

测试注意事项

  • 修改代码后需重新加载扩展
  • 重新注册FCM Token,确保新配置生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:44:54