我正在开发一个应用程序的推送通知使用FCM,当应用程序在后台或终止,并收到新的通知,我需要保存此通知本地的数据(SQLITE),没有点击通知或重新打开应用程序再次,通知不会在应用程序中读取,除非点击。
这是我的通知处理程序. dart
import 'dart:async';
import 'dart:io';
import 'package:eshaar/model/message.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:eshaar/model/database_helper.dart';
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
new FlutterLocalNotificationsPlugin();
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
print("onBackgroundMessage: $message");
//_showBigPictureNotification(message);
return Future<void>.value();
}
Future onSelectNotification(String payload) async {
}
class NotificationHandler {
FirebaseMessaging _fcm = FirebaseMessaging();
StreamSubscription iosSubscription;
DatabaseHelper db = new DatabaseHelper();
static final NotificationHandler _singleton =
new NotificationHandler._internal();
factory NotificationHandler() {
return _singleton;
}
NotificationHandler._internal();
initializeFcmNotification() async {
var initializationSettingsAndroid =
new AndroidInitializationSettings('mipmap/ic_launcher');
var initializationSettingsIOS = new IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = new InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
if (Platform.isIOS) {
iosSubscription = _fcm.onIosSettingsRegistered.listen((data) {
// save the token OR subscribe to a topic here
});
_fcm.requestNotificationPermissions(IosNotificationSettings());
} else {
_saveDeviceToken();
}
_fcm.configure(
onMessage: (Map<String, dynamic> message) async {
print("---------------------On Message--------------------");
displayNotification(message['data']['title'],message['data']['body']);
_saveNotificationToLocal(message);
},
onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler ,
onLaunch: (Map<String, dynamic> message) async {
print("---------------------On Lunch--------------------");
_saveNotificationToLocal(message);
},
onResume: (Map<String, dynamic> message) async {
print("---------------------On Resume--------------------");
_saveNotificationToLocal(message);
},
);
}
_saveNotificationToLocal(Map<String, dynamic> message){
String sender_id = message['data']['sender_id'];
String message_id = message['data']['message_id'];
String title = message['data']['title'];
String body = message['data']['body'];
String del_time = getCurrentDateTime();
Messages msg = new Messages(sender_id,message_id,title,body,del_time);
db.saveMessages(msg);
}
String getCurrentDateTime(){
var now = new DateTime.now();
var formatter = new DateFormat('MMM d yy h:mm a');
String formatted = formatter.format(now);
return formatted;
}
/// Get the token, save it to the database for current user
_saveDeviceToken() async {
String fcmToken = await _fcm.getToken();
}
Future<void> onDidReceiveLocalNotification(
int id, String title, String body, String payload) async {
// display a dialog with the notification details, tap ok to go to another page
}
void displayNotification(String title,String body) async{
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description',
importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0, '$title', '$body', platformChannelSpecifics,
payload: 'item x');
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ot.eshaar.eshaar">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name=".Application"
android:label="eshaar"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<meta-data
android:name="com.google.firebase.messaging.android.channel_id"
android:value="mmne" />
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
</application>
</manifest>
- Flutter医生-v**
[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.14.4 18E226, locale
en-US)
• Flutter version 1.9.1+hotfix.6 at /Users/mahmoudabdelaziz/Desktop/flutter
• Framework revision 68587a0916 (3 months ago), 2019-09-13 19:46:58 -0700
• Engine revision b863200c37
• Dart version 2.5.0
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/mahmoudabdelaziz/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling
support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android
Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build
1.8.0_152-release-1343-b01)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.0)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.0, Build version 11A420a
• CocoaPods version 1.8.4
[!] Android Studio (version 3.4)
• Android Studio at /Applications/Android Studio.app/Contents
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build
1.8.0_152-release-1343-b01)
[✓] IntelliJ IDEA Community Edition (version 2018.3.3)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin version 31.3.4
• Dart plugin version 183.5153.38
[✓] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API
28) (emulator)
6条答案
按热度按时间kognpnkq1#
在我的例子中,FCM
onBackgroundMessage
只在有效负载上没有通知时触发。如果有效负载上有通知,它发送的是在系统托盘上显示通知。但是如果你想对发送的数据进行一些编译,那么就删除有效负载上的通知,只发送数据。
2021年更新
请确保在通知中添加
content_available
,这对我现在有效。我正在使用firebase_messaging
prereplase。在这个版本中,他们已经启用了开箱即用的后台处理程序。https://pub.dev/packages/firebase_messaging/versions/8.0.0-dev.14
cygmwpex2#
虽然很晚了,但我还是会回应其他人的帮助。
这里的问题与处理无关,而是与您从Firebase控制台发送的消息类型有关。仅当消息是数据消息或具有数据有效负载的通知消息时,才调用
onBackgroundMessage
回调。并确保您的消息也添加了
click_action: 'FLUTTER_NOTIFICATION_CLICK'
。从Firebase控制台生成消息也有一些问题,所以尝试直接从服务器生成消息。更多细节请查看此线程。
bis0qfac3#
请确保你在发送通知时添加了click_action属性.确保它的值与你在android intent中提供的值匹配.
sr4lhrrt4#
在myBackgroundMessageHandler中,您需要调用该函数将通知保存到本地存储。
例如
希望能有所帮助。
vmjh9lq95#
使用 Postman 发送此内容和“content_available”:true触发器_firebase消息传递背景处理程序
kognpnkq6#
在后台处理程序消息的顶部添加这一行. @pragma('vm:entry-point')