Firebase Messaging 如何清除通知?

5

我正在使用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);
      },
    );
  }

_showPushNotificationDialog方法将在每次调用onMessageonResumeonLaunch方法时被调用。

遇到的问题是,当我的应用处于后台或终止模式时,通知会来,并且会点击通知栏时,一切都正常。但当我去其他页面并返回到之前的页面时,每次都会调用_firebaseMessaging.configure(....方法,它有数据,所以每次都会弹出我的警报对话框。

那么,我该如何清除通过通知栏点击的通知?


你找到解决方法了吗?我也遇到了同样的问题 @govaadiyo - Evripides Kyriacou
抱歉,Nope @EvripidesKyriacou - Govaadiyo
5个回答

2
我也遇到了这个问题。我有一个解决方法: 我创建了一个带有静态布尔值和静态方法的类:
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);
}

我希望这能对你有所帮助


这不是最好的解决方案,但它能够工作,谢谢。 - Itamar Garcia

1
这里有另一个解决方案,使用通知中的唯一值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);
  },
);

1

我知道,这看起来有点丑陋,但是我只知道这种方式:

  1. 添加flutter_local_notifications
  2. import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  1. 只需创建 final fln = FlutterLocalNotificationsPlugin();

  2. 需要时使用 fln.cancelAll()


1
我为了防止onLaunch和onResume方法一遍又一遍地运行,会检查当前通知与上一条通知是否相同(我使用shared_preferences)。
以下是代码片段:
_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');
  }
}

0

尝试在initState中配置firebaseMessaging而不是在自定义方法中。那应该可以工作 :)


这个方法从initState()中调用 :) - Govaadiyo
@Govaadiyo:也许我遇到了和你一样的问题(现在我认为我可能误解了你最初的问题)。我在GitHub上开了一个问题,但没有得到官方Flutter开发人员的答复。尽管如此,我找到了一个解决方法,似乎对我有用。也许它也能帮助你?你可以在这里找到我的问题和解决方法:https://github.com/flutter/flutter/issues/32698#issuecomment-494766329 - ehhc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接