使用Flutter+FCM的sendMulticast时,如何添加FLUTTER_NOTIFICATION_CLICK?
正确添加FCM通知的click_action以打开Flutter应用内特定页面
核心问题:字段名格式错误
你添加的clickAction是驼峰命名,但FCM的通知负载字段要求使用下划线命名的click_action,这是导致发送失败的直接原因。修正字段名即可解决该问题,同时建议补充自定义数据用于后续页面跳转。
修改后的Firebase Function代码
import functions = require("firebase-functions"); import admin = require("firebase-admin"); admin.initializeApp(); exports.sendNotificationToFCMToken = functions.firestore.document("chat_rooms/{chatRoomId}/messages/{messageId}") .onCreate(async (snapshot: functions.firestore.QueryDocumentSnapshot, context) => { const senderUid: string = snapshot.data().sender_uid; const recipientsUid: string[] = snapshot.data().recipients_uid; const message: string = snapshot.data().message; const chatRoomId = context.params.chatRoomId; // 获取房间ID用于跳转参数传递 const db = admin.firestore(); const fcm = admin.messaging(); // 替换forEach为for...of,确保异步操作按顺序执行 for (const uid of recipientsUid) { const recipientTokensSnapshot = await db .collection("users_data") .doc(uid) .collection("tokens") .get(); const recipientTokens = recipientTokensSnapshot .docs.map((doc) => doc.data().token); const notificationPayload = { notification: { title: senderUid, body: message, click_action: "FLUTTER_NOTIFICATION_CLICK" // 修正为下划线命名的字段 }, data: { // 添加自定义数据,用于Flutter端判断跳转目标页面 screen: "/chat-room", chatRoomId: chatRoomId }, tokens: recipientTokens, }; const response = await fcm.sendMulticast(notificationPayload); console.log(`给用户${uid}发送通知:${response.successCount}成功,${response.failureCount}失败`); } });
额外关键配置
- AndroidManifest.xml 配置
在Flutter项目的android/app/src/main/AndroidManifest.xml中,给MainActivity添加对应的intent filter,确保点击通知能唤起应用:
<activity android:name=".MainActivity" android:exported="true"> <!-- 原有配置保持不变 --> <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
- Flutter端处理通知点击
在Flutter代码中监听通知打开事件,根据payload中的data字段跳转到指定页面:
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; void setupNotificationListener(BuildContext context) { // 处理应用处于后台时点击通知的情况 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { final String? targetScreen = message.data['screen']; if (targetScreen == '/chat-room') { final String? chatRoomId = message.data['chatRoomId']; Navigator.pushNamed( context, targetScreen, arguments: chatRoomId, ); } }); // 处理应用完全关闭时点击通知的情况(建议在MaterialApp初始化后调用) FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) { if (message != null) { final String? targetScreen = message.data['screen']; if (targetScreen == '/chat-room') { final String? chatRoomId = message.data['chatRoomId']; Navigator.pushNamed( context, targetScreen, arguments: chatRoomId, ); } } }); }
注意事项
- 原代码使用
forEach(async (uid) => {})会导致异步操作无法按顺序执行,函数可能提前结束,改用for...of循环可保证每个用户的通知发送完成后再处理下一个。 data字段中的自定义参数可根据业务需求调整,用于传递跳转所需的页面参数。
内容的提问来源于stack exchange,提问作者David A.
相关产品推荐
相关产品推荐

