Flutter Firebase Cloud Messaging 如何自动关闭/取消通知?

Posted

技术标签:

【中文标题】Flutter Firebase Cloud Messaging 如何自动关闭/取消通知?【英文标题】:Flutter Firebase Cloud Messaging how to Auto Dismiss/Cancel a notification? 【发布时间】:2022-01-17 18:52:02 【问题描述】:

我已经成功地通过控制台以及从我的 NodeJs 服务器接收 FCM 消息(在我的手机上)。但是我如何发送和接收将到达我的手机的 FCM 消息,执行一些任务,然后自行自动取消/关闭?

这在 Flutter with FCM 中是否可行? 在android中,我们曾经有public Notification.Builder setTimeoutAfter (long durationMs)

更多的是用于 ping 客户端应用程序...并从应用程序本地存储中检索一些数据。因为它可以自动完成,所以我想这样做而不会给用户带来麻烦。

【问题讨论】:

为什么不使用 Job Scheduler?要ping(智能手机应用程序是否存在)或读取本地数据,您可以使用Job Scheduler ios:backgroudbatch。 用户似乎在使用外部系统,例如 cronjob 服务器。 是的,这是真的。我们想使用像 CronJob 这样的外部服务。我们不需要像 JobScheduler 或 Background Fetch 这样的背景检查。 【参考方案1】:

这些是完成以下步骤的步骤

在不打扰用户的情况下接收通知(在系统托盘中没有任何警报的静默方式) 让 localNotification Pkg 启动进度通知 执行后台任务并完成后 通过 LocalNotifications Pkg 取消通知

确保您的 .yaml 文件中包含以下内容...在解决此问题时,我有以下版本:

  firebase_messaging: ^11.1.0
  firebase_core: ^1.10.0
  flutter_local_notifications: ^9.1.

对于本地通知包,让我们创建一个类来使用它的服务

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class LocalNotificationService 
  static final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();

  static void initialize(BuildContext context) 
    final InitializationSettings initializationSettings = InitializationSettings(
        android: const AndroidInitializationSettings("@mipmap/your_icon"));

    _notificationsPlugin.initialize(initializationSettings);
  


//=================================================
//==============this is the update notification

  static Future<void> showProgressNotification() async 
    const int maxProgress = 5;
    for (int i = 0; i <= maxProgress; i++) 
      await Future<void>.delayed(const Duration(seconds: 1), () async 
        final AndroidNotificationDetails androidPlatformChannelSpecifics =
        AndroidNotificationDetails('progress channel', 'progress channel',
            channelDescription: 'progress channel description',
            channelShowBadge: false,
            importance: Importance.max,
            priority: Priority.high,
            playSound: false,
            showProgress: true,
            maxProgress: maxProgress,
            progress: i);
        final NotificationDetails platformChannelSpecifics =
        NotificationDetails(android: androidPlatformChannelSpecifics);
        await _notificationsPlugin.show(
            0,//I use this id to cancel it from below method
            'progress notification title',
            'progress notification body',
            platformChannelSpecifics,
            payload: 'item x');
      );
    
  

  //=========================and this is for the ProgressNotification to be cancelled
  static Future<void> cancelNotification() async 
    await _notificationsPlugin.cancel(0);
  

//end of class

让你在你的Widget的init方法中初始化它

@override
  void initState()  
    // TODO: implement initState
    super.initState();

    LocalNotificationService.initialize(context);

最后...这是您的 Main() 和***处理程序的外观

//Receive message when app is in background/minimized 
//THIS IS THE TOP LEVEL HANDLER.. as it is outside the scope of main()
Future<void> backgroundHandler(RemoteMessage message) async
  print("from the Background Handler Top Function()..............");
  print(message.data.toString()); 
  //now for the localNotification to take over
  await LocalNotificationService.showProgressNotification();
  await Future<void>.delayed(const Duration(seconds: 2));//faking task delay
  await LocalNotificationService.cancelNotification();//by default I have made id=0




void main() async
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(backgroundHandler);//this has to be a TOP LEVEL METHOD
  runApp(MyApp());

在服务器端发送通知时确保只有数据...见@Junsu Cho 回答

【讨论】:

【参考方案2】:

ios 是不可能的 android 是可能的,删除通知负载


"to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
"notification":
    
        "title": "title"
    
"data":
    
      "data" : "data"
    


"to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
"data":
    
      "data" : "data"
    

【讨论】:

是的,我们确实尝试过...这不会使通知出现在系统托盘中...但我们希望通知出现,让任务完成...然后自行取消。这才是真正的问题……有什么想法吗? 由于 fcm 是一种单向协议,因此无法自动关闭。我的想法是使用 fcm 推送运行服务,使用服务结束任务,然后终止服务。 是的,回到这里我们也开始这么想了。所以让我们给它几天时间,否则我们会接受你的建议。

以上是关于Flutter Firebase Cloud Messaging 如何自动关闭/取消通知?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 中的 cloud_firestore 和 firebase_auth 兼容性问题

如何在不使用 Firebase Cloud Messaging 控制台的情况下向 Flutter/Firebase Cloud Messaging 上的特定设备发送通知 [重复]

Firebase Cloud Messaging 无法在带有 Flutter 应用程序的 Android 上运行

Firebase Cloud Firestore 在 Flutter 中获取地图数组

如何使用 graphql 从 Firebase 使用 Flutter 从 Cloud Firestore 获取数据?

Flutter Web App 无法访问 Firebase Cloud Firestore