使用minishlink/webpush时推送通知被覆盖的问题求助
Web推送通知被覆盖问题排查与解决
问题描述
我查阅了不少通知被覆盖的相关问题,但仍未找到解决方案。使用minishlink/webpush向Web浏览器发送推送通知时,旧通知持续被新通知覆盖,新通知不会弹窗提示用户,而是直接替换通知面板中的旧通知。已添加唯一标识,但问题仍未解决。
相关代码
PHP推送服务类(PushNotificationService)
<?php namespace common\components; use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; use frontend\models\notification\UserSubscriptions; use Exception; class PushNotificationService { public static function sendNotificationToUser($userId, $title, $message, $url) { // VAPID keys (generated earlier) $publicKey = 'BIMBZr3K1YdaKwVSahjdgdrgz1aafesfsfBco8Tte496whQnaEvVvRTkckuYlAfwSPrvEcLvmGQB-Zy2YbEj1UM'; $privateKey = '9tjiAzpQ5sdw0KUOnj-yWA9alTYBC9bgku9orpql9uI'; // Retrieve subscription from the database $userSubscription = UserSubscriptions::find()->where(['user_id' => $userId])->all(); if ($userSubscription) { // Create the WebPush instance $webPush = new WebPush([ 'VAPID' => [ 'subject' => 'mailto:mail@mail.com', 'publicKey' => $publicKey, 'privateKey' => $privateKey, ], ]); foreach ((array) $userSubscription as $sendNotification) { $subscription = Subscription::create(json_decode($sendNotification->subscription, true)); $uniqId = uniqid(); // Prepare the payload with a timestamp and tag $payload = json_encode([ 'title' => $title, 'message' => $message, 'icon' => "/images/logo-255x255.png", 'tag' => "my-notification-$uniqId", 'timestamp' => time(), 'url' => '//www.google.com', 'data' => [ 'notificationId' => $uniqId, ], 'requireInteraction' => true, 'urgency' => 'high', ]); // Send the notification if ($webPush->sendOneNotification($subscription, $payload)) { \common\models\myTools\Mydebug::dumpFileA("Success"); } else { \common\models\myTools\Mydebug::dumpFileA("Error"); } } // Flush messages (actually send them) $webPush->flush(); } } }
Service Worker的Push事件监听器
self.addEventListener('push', event => { const data = event.data.json(); const options = { body: data.message, icon: data.icon, tag: data.tag, data: { notificationId: data.data.notificationId, }, requireInteraction: data.requireInteraction, urgency: data.urgency }; event.waitUntil( self.registration.showNotification(data.title, options) ); });
排查与解决步骤
确保通知Tag绝对唯一
uniqid()在高并发场景下可能出现重复,建议替换为UUID生成更可靠的唯一标识。比如使用ramsey/uuid库:// 先安装依赖:composer require ramsey/uuid use Ramsey\Uuid\Uuid; $uniqId = Uuid::uuid4()->toString();验证Service Worker接收的Tag正确性
在Service Worker中添加日志,确认每个通知的Tag是否唯一:self.addEventListener('push', event => { const data = event.data.json(); console.log('当前通知Tag:', data.tag); // 打印Tag到控制台 const options = { body: data.message, icon: data.icon, tag: data.tag, data: { notificationId: data.data.notificationId, }, requireInteraction: data.requireInteraction, urgency: data.urgency }; event.waitUntil( self.registration.showNotification(data.title, options) ); });打开浏览器开发者工具的Console标签,查看每次推送的Tag是否不同。
强制更新Service Worker
浏览器可能缓存了旧的Service Worker代码,导致新的Tag逻辑未生效。在开发者工具的Application → Service Workers面板中,点击「Update」按钮强制刷新。检查浏览器通知权限与设置
确认网站已获得通知权限,且浏览器未将通知设置为静默模式(部分浏览器在通知过多时会自动转为静默)。避免批量推送过频繁
短时间内批量发送通知可能被浏览器合并处理,建议添加间隔时间,或分批次推送。
内容的提问来源于stack exchange,提问作者yai
相关产品推荐
相关产品推荐

