FCM API问题:无法接收PHP服务器发送的通知
问题排查与解决方案
1. JavaScript参数传递错误
你的send_notification函数定义了3个参数(empno,charge,op),但调用时只传了2个参数:
await send_notification("Hi Leo","This is a test notification");
这会导致第三个参数op为undefined,最终AJAX发送的body字段值为空。PHP接收后,$_POST["body"]不存在,发送的通知内容为空,甚至可能触发Firebase消息发送异常。
修正方法:调整函数参数与调用逻辑匹配:
// 修改函数参数为2个,对应标题和内容 function send_notification(title, body){ return $.ajax({ url: '/notification_server/firebase_server.php', type: 'POST', data:{ "employee": title, "body": body }, cache: false }) } // 调用时传递正确参数 (async() => { await send_notification("Hi Leo","This is a test notification"); })();
2. PHP端未捕获异常,无法定位发送失败原因
当前PHP代码没有捕获$messaging->send($message)可能抛出的异常,比如设备令牌无效、权限不足、服务配置错误等问题,即使发送失败也无法获取错误信息。
修正方法:添加异常捕获逻辑,输出错误详情:
<?php require __DIR__.'/vendor/autoload.php'; use Kreait\Firebase\Factory; use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Exception\MessagingException; try { $factory = (new Factory) ->withServiceAccount('admin.json') ->withDatabaseUri("https://nfr-qtr-electric-billing-default-rtdb.firebaseio.com"); $deviceToken = '.....'; // 确保此处为当前设备的有效令牌 $messaging = $factory->createMessaging(); $message = CloudMessage::withTarget('token', $deviceToken) ->withNotification(['title' => $_POST["employee"], 'body' => $_POST["body"]]); $messaging->send($message); echo "消息发送成功"; } catch (MessagingException $e) { echo "发送失败:" . $e->getMessage(); } catch (\Exception $e) { echo "未知错误:" . $e->getMessage(); } ?>
执行AJAX请求后查看响应内容,即可明确Firebase消息发送状态。
3. Android端Firebase Messaging服务未注册
如果MyFirebaseMessagingService未在AndroidManifest.xml中注册,系统无法将消息传递到该服务,自然不会触发onMessageReceived方法。
需在Manifest的<application>标签内添加注册代码:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
4. 设备令牌有效性问题
确保PHP中填写的$deviceToken是当前测试设备的有效令牌:
- 在
MyFirebaseMessagingService的onNewToken方法中打印令牌,或保存到本地/服务器,确保使用最新令牌; - 若令牌过期或无效,Firebase会返回发送失败,通过PHP的异常捕获可查看对应错误信息。
5. Android 8.0+通知渠道缺失
Android 8.0(API 26)及以上版本必须配置通知渠道,否则通知无法显示。你的代码未创建渠道,需补充逻辑:
修改sendLocalNotification方法:
private void sendLocalNotification(String notificationTitle, String notificationBody) { // 创建通知渠道(适配Android 8.0+) String channelId = "default_notification_channel"; String channelName = "默认通知"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } Intent intent = new Intent(this, record_viewer.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 适配Android 12+,添加FLAG_IMMUTABLE PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); // 创建通知时指定渠道ID NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId) .setAutoCancel(true) .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(pendingIntent) .setContentTitle(notificationTitle) .setContentText(notificationBody) .setSound(defaultSoundUri); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(1234, notificationBuilder.build()); }
内容的提问来源于stack exchange,提问作者user20307020
相关产品推荐
相关产品推荐

