firebase_messaging 如何清除通知?
Posted
技术标签:
【中文标题】firebase_messaging 如何清除通知?【英文标题】:firebase_messaging how to clear notification? 【发布时间】:2019-09-26 04:51:12 【问题描述】:我正在使用firebase_messaging 当通知到来时,我正在显示警报对话框。下面是我的代码。
showNotification(BuildContext context)
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
print('on message $message');
_showPushNotificationDialog(message['notification']['title'],
message['notification']['body'], context);
,
onResume: (Map<String, dynamic> message) async
print('on resume $message');
_showPushNotificationDialog(
message['data']['title'], message['data']['body'], context);
,
onLaunch: (Map<String, dynamic> message) async
print('on launch $message');
_showPushNotificationDialog(
message['data']['title'], message['data']['body'], context);
,
);
onMessage、onResume、onLaunch方法调用时,每次调用_showPushNotificationDialog
方法。
面临的问题,例如当我的应用程序处于后台或终止模式时,会出现通知并点击通知托盘,一切正常。但是当我转到其他页面并一直返回到上一个时,_firebaseMessaging.configure(....
方法调用并且它有数据,所以每次我的警报对话框都会弹出。
那么如何清除被通知托盘点击的通知呢?
【问题讨论】:
你找到解决方案了吗,我也有同样的问题@govaadiyo 对不起,不行@EvripidesKyriacou 【参考方案1】:我也遇到了这个问题。我有这个解决方法: 我所做的是用静态布尔和静态方法创建一个类:
class MessagingWidget
static bool _isConfigured = false;
static void configuringFirebase(User currentUser, BuildContext context)
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
if (!_isConfigured)
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
print("onMessage: $message");
final notification = message['notification'];
,
onLaunch: (Map<String, dynamic> message) async
print("onLaunch: $message");
final notification = message['data'];
if(notification['title']!=null)
if(notification['title']=="Testo")
goToAppointmentsScreen(currentUser,context);
,
onResume: (Map<String, dynamic> message) async
print("onResume: $message");
final notification = message['data'];
if(notification['title']!=null)
if(notification['title']=="Testo")
goToAppointmentsScreen(currentUser,context);
,
);
_isConfigured = true;
void goToAppointmentsScreen(User currentUser1, BuildContext context1) async
final bool backFromAppointmentsScreen=await Navigator.push(
context1,
MaterialPageRoute(builder: (context) => Appointment(
currentUser1),
),
);
然后我在路由小部件的 init 中调用了这个方法:
@override
void initState()
super.initState();
refreshServices();
getDirectionBasedOnLocation();
MessagingWidget.configuringFirebase(currentUser, context);
希望对你有帮助
【讨论】:
这不是最好的解决方案,但它有效,谢谢【参考方案2】:为了防止 onLaunch 和 onResume 方法一次又一次地运行,我所做的是检查当前通知与最后一个通知(我使用 shared_preferences)
这是sn-p:
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
print('on message $message');
onMessageReceived(context, message);
,
onResume: (Map<String, dynamic> message) async
print('on resume $message');
onLaunch(context, message);
,
onLaunch: (Map<String, dynamic> message) async
print('on launch $message');
onLaunch(context, message);
,
);
.
.
.
void onLaunch(BuildContext context, Map<String, dynamic> remoteMessage) async
var pref = SharedPreferences.getInstance();
var data = remoteMessage['data'] ?? remoteMessage;
String lastData = '';
await pref.then((prefs)
lastData = prefs.get('remote_message');
);
if ((data['type'] != null || data['id'] != null) &&
data.toString() != lastData)
toDetailPageFromPush(
context,
data['type'],
data['id'],
);
pref.then((prefs)
prefs.setString('remote_message', data.toString());
);
else
print('on launch error $remoteMessage');
【讨论】:
【参考方案3】:这是另一种解决方案,使用通知中的唯一值 message_id,因此我们可以使用共享偏好保存通知的最后一个 id 并与当前通知进行比较:
processNotification(message, BuildContext context) async
try
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String lastMessageId = sharedPreferences.getString('last_message_id');
String currentMessageId = message['data']['google.message_id'];
//COMPARE NOTIFICATIONS ID
if(currentMessageId != lastMessageId)
//SET LAST NOTIFICATION ID
sharedPreferences.setString('last_message_id', currentMessageId);
//SHOW A DIALOG OR NAVIGATE TO SOME VIEW, IN THIS CASE TO A VIEW
String screen = message['data']['screen'];
Navigator.of(context).pushNamed(screen);
catch (e)
print('ERROR PROCESSING NOTIFICATION');
print(e);
现在我们可以在配置中调用这个函数了:
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
print('on message $message');
processNotification(context,message);
,
onResume: (Map<String, dynamic> message) async
print('on resume $message');
processNotification(context,message);
,
onLaunch: (Map<String, dynamic> message) async
processNotification(context,message);
,
);
【讨论】:
【参考方案4】:尝试在 initState 中而不是在自定义方法中配置 firebaseMessaging。这应该工作:)
【讨论】:
这个方法从 initState 调用:) @Govaadiyo :也许我遇到了和你一样的问题(现在我想我可能误解了你最初的问题)。我打开了一个 github issue,但没有得到官方 Flutter 开发者的答复。尽管如此,我找到了一个似乎对我有用的解决方法。也许它对你也有帮助?你可以在这里找到我的问题和我的工作:github.com/flutter/flutter/issues/32698#issuecomment-494766329【参考方案5】:我知道,有点丑,但我只知道这样:
-
添加flutter_local_notifications
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
只需创建final fln = FlutterLocalNotificationsPlugin();
并在需要时使用fln.cancelAll()
。
【讨论】:
以上是关于firebase_messaging 如何清除通知?的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序通过使用 firebase_messaging 的推送通知终止时如何接收自定义数据?
Flutter 推送通知应用背景:firebase_messaging
使用颤振 firebase_messaging 插件发送通知声音