私はFCMを使用して通知をプッシュするためのアプリを開発しています。バックグラウンドのアプリまたは終了して新しい通知を受け取ったときに、通知をクリックしたり、アプリを再度開いたりせずに、この通知のデータを(SQLITE)にローカルに保存する必要があります。 、クリックしない限り、通知はアプリで読み込まれません。助言がありますか?
これは私のNotificationHandler.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>
フラッタードクター-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)
遅いですが、他の人が役に立てるように返信します。
ここでの問題は処理ではなく、Firebaseコンソールから送信するメッセージのタイプです。 onBackgroundMessage
callBackは、メッセージがデータメッセージまたはデータペイロードを含む通知メッセージである場合にのみ呼び出されます。
また、メッセージにclick_action: 'FLUTTER_NOTIFICATION_CLICK'
を追加しました。
また、Firebaseコンソールからのメッセージの生成にも問題があるため、サーバーから直接メッセージを生成してみてください。詳細については、こちら thread をご覧ください。
私の場合、ペイロードに通知がない場合のみ、FCM onBackgroundMessage
がトリガーされます。ペイロードに関する通知がある場合、それが送信することは、システムトレイに通知を表示します。
ただし、送信されたデータに対してコンパイルを行う場合は、ペイロードのnotificationを削除して、dataのみを送信します。
{
"to" : "Place the token of the test device here",
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"priority": "high",
"data" : {
"type" : "anything",
"title": "Title of Your Notification in Title",
"key_1" : "Value for key_2"
}
}
MyBackgroundMessageHandlerでその関数を呼び出して、通知をローカルストレージに保存する必要があります。
例えば
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
print("onBackgroundMessage: $message");
//_showBigPictureNotification(message);
NotificationHandler()._saveNotificationToLocal(message);
return Future<void>.value();
}
お役に立てば幸いです。
通知の送信中に、click_actionプロパティを追加したことを確認してください。その値がAndroidインテントで指定したものと一致することを確認してください。
{
notification: {
title: 'Title',
body: 'Body',
click_action: 'FLUTTER_NOTIFICATION_CLICK'
} }