CodeIgniter4中FCM请求成功但PC未收到通知的问题求助
问题排查与解决方案
FCM返回成功但PC端收不到通知,而Firebase控制台能正常发送,核心问题集中在消息结构适配Web端要求和前端Service Worker配置缺失这两点,以下是具体修复步骤:
1. 修正FCM消息结构
你当前的消息只包含基础notification字段,缺少Web推送必需的优先级和交互配置。修改send_notif函数的$fields结构:
function send_notif($token, $serverKey, $title, $body){ $url = 'https://fcm.googleapis.com/fcm/send'; $fields = [ "to" => $token, "notification" => [ "body" => $body, // 改用传入的动态内容,替换硬编码的"SOMETHING" "title" => $title, "requireInteraction" => true, // 防止通知自动关闭 "icon" => "你的图标URL" // 可选,建议添加以匹配控制台发送的通知样式 ], "webpush" => [ "headers" => [ "Urgency" => "high" // 设置高优先级,确保通知及时送达 ] ], "priority" => "high" // 全局优先级声明 ]; $headers = array('Authorization:key='.$serverKey.'','Content-Type:application/json'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 移除不安全的SSL禁用配置,保留默认验证 // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); $result = curl_exec($ch); if ($result === FALSE) { die('Curl failed: ' . curl_error($ch)); } curl_close($ch); }
2. 配置前端Service Worker
Web端FCM推送必须依赖Service Worker接收通知,你当前的代码仅获取了token,未处理消息接收逻辑:
步骤1:添加firebase-messaging-sw.js文件
在项目根目录创建该文件,填入你的Firebase配置:
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js'); firebase.initializeApp({ apiKey: "你的API_KEY", authDomain: "你的AUTH_DOMAIN", projectId: "你的PROJECT_ID", storageBucket: "你的STORAGE_BUCKET", messagingSenderId: "你的MESSAGING_SENDER_ID", appId: "你的APP_ID" }); const messaging = firebase.messaging(); // 处理前台消息(页面打开时) messaging.onMessage((payload) => { const notificationTitle = payload.notification.title; const notificationOptions = { body: payload.notification.body, icon: payload.notification.icon }; return self.registration.showNotification(notificationTitle, notificationOptions); }); // 处理后台消息(页面关闭/最小化时) messaging.setBackgroundMessageHandler((payload) => { const notificationTitle = payload.notification.title; const notificationOptions = { body: payload.notification.body, icon: payload.notification.icon }; return self.registration.showNotification(notificationTitle, notificationOptions); });
步骤2:在主脚本中注册Service Worker
在获取token的逻辑前添加:
const messaging = firebase.messaging(); // 注册Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/firebase-messaging-sw.js') .then(function(registration) { console.log('Service Worker 注册成功'); messaging.useServiceWorker(registration); }) .catch(function(err) { console.log('Service Worker 注册失败:', err); }); } // 原有的权限请求和token获取逻辑 messaging .requestPermission() .then(function () { return messaging.getToken() }) .then(function(token) { console.log(token) // 后续的点击事件逻辑... }) .catch(function (err) { console.log("Unable to get permission to notify.", err); });
3. 其他检查项
- 确认浏览器已允许该网站发送通知(可在浏览器设置->隐私与安全中查看);
- 检查Service Worker状态:打开浏览器开发者工具->Application->Service Workers,确保处于活跃状态;
- 确保前端传入的
serverKey是Firebase项目的云消息传递API密钥(而非其他密钥)。
内容的提问来源于stack exchange,提问作者Fajar Alam
相关产品推荐
相关产品推荐

