flutter - firebase_messaging onBackgroundMessage local_notifications
问题描述
当应用程序关闭或在后台时,我试图停止来自 firebase_message 的默认通知。
我想在应用程序关闭或使用 local_notifications 插件在后台显示自定义通知,该插件按预期工作,发送消息时存在问题,应用程序显示相同的通知两次,默认通知为 1,另一个与自定义通知。
我无法实现停止默认通知。谁能在这里指出我的错误?
初始代码来自 firebase 消息传递示例,删除不必要的片段并添加自定义通知。
还附上了当前的图像(不良行为)
如前所述,相同的通知显示了两次,想要摆脱图像上显示的第一个通知。
这是我的代码:
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'utils/utils.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('_firebaseMessagingBackgroundHandler');
Future onDidReceiveLocalNotification(
int? id, String? title, String? body, String? payload) async {
print('onDidReceiveLocalNotification');
}
final channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.high,
);
var flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
final initializationSettingsAndroid =
AndroidInitializationSettings('icon_app');
final initializationSettingsIOS = IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
final initializationSettingsMacOS = MacOSInitializationSettings();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
final initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: onSelectNotification,
);
///Not able to stop default notification
///there fore when custom notification is called
///result is 2 notifications displayed.
NotificationDetails _notificationDetails;
_notificationDetails = await customNotification(message: message);
flutterLocalNotificationsPlugin.show(
message.notification.hashCode,
message.notification!.title,
message.notification!.body,
_notificationDetails,
payload: '',
);
// await Firebase.initializeApp();
print('Handling a background message ${message.messageId}');
}
Future<NotificationDetails> customNotification(
{required RemoteMessage message}) async {
print('notificationDetailsBigImage');
final utils = Utils();
final bigPicturePath = await utils.downloadAndSaveFile(
url: 'https://picsum.photos/536/354', fileName: 'bigPicture');
final bigPictureStyleInformation = BigPictureStyleInformation(
FilePathAndroidBitmap(bigPicturePath),
hideExpandedLargeIcon: true,
);
final androidPlatformChannelSpecifics = AndroidNotificationDetails(
'big text channel name',
'big text channel name',
'big text channel description',
styleInformation: bigPictureStyleInformation,
icon: 'icon_app',
color: const Color.fromARGB(255, 255, 0, 0),
ledColor: const Color.fromARGB(255, 255, 0, 0),
ledOnMs: 1000,
ledOffMs: 500,
);
return NotificationDetails(android: androidPlatformChannelSpecifics);
}
Future<void> onDidReceiveLocalNotification(
int? id, String? title, String? body, String? payload) async {
print('onDidReceiveLocalNotification');
}
Future<void> onSelectNotification(String? payload) async {
print('onSelectNotification');
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
runApp(MessagingExampleApp());
}
/// Entry point for the example application.
class MessagingExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Messaging Example App',
theme: ThemeData.dark(),
routes: {
'/': (context) => Application(),
},
);
}
}
/// Renders the example application.
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
late String _token;
@override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then((message) {
print('instance');
if (message != null) {
print('do stuff');
}
});
FirebaseMessaging.onMessage.listen((message) {
print('onMessage');
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print('A new onMessageOpenedApp event was published!');
});
}
@override
Widget build(BuildContext context) {
return Scaffold();
}
}
解决方案
好吧,这是我这边的一个错误。阅读 FCM 文档后,似乎有两种类型的 FCM 推送:通知和数据。
通知具有默认行为,即显示当前默认的推送通知。设置数据消息推送时,不会触发默认行为,让您决定做什么。
通知负载示例
"token"=> "...."
"data" => ["notificationDisplay" => "bigImage"],
"notification" => [ //<-- this will trigger a Push notification
"title" => $title,
"body" => $message,
],
...
数据消息负载示例
"token"=> "...."
"data" => ["notificationDisplay" => "bigImage"],
// without notification on payload will trigger
//Data Message, as expected you will need to declare
//all fields you logic expects on data structure.
也就是说两个防止默认默认推送,都需要发送数据消息并添加相应的逻辑。
推荐阅读
- c++ - 什么是模板
意思是? - javascript - 未捕获的错误:目标容器不是 DOM 元素。VSCode 实时服务器
- java - 多模块项目中的 Java JaCoCo 集成报告
- laravel - 数据库中的值数组,每小时(制作图表)
- swift - 为什么 CIContext.init() 不应该返回 nil?
- python - python中的康普顿散射
- docker - 如何在高山基础 docker 映像中设置时区?
- html - 用 Excel 打印的网站 html 链接有奇怪的空白
- widget - 如何以编程方式设置 Databricks 小部件行为?
- sql - SQL - 计算客户一起购买的产品的重叠