我在我的Flutter应用程序中将 firebase_messaging 库用于Firebase推送通知。
当前,我的firebase_messaging版本是 firebase_messaging:^ 5.1.5 ,该版本最近更新为最新版本。
我正在尝试在后台以及终止应用程序时接收通知。
我已按照firebase_messaging文档中提到的所有步骤进行操作,但不幸的是,我在抖动中遇到了上述错误。
这是我在dart中的通知处理程序类
notification_handler.dart
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
class NotificationHandler {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
FirebaseMessaging _fcm = FirebaseMessaging();
StreamSubscription iosSubscription;
static final NotificationHandler _singleton =
new NotificationHandler._internal();
factory NotificationHandler() {
return _singleton;
}
NotificationHandler._internal();
Future<dynamic> myBackgroundMessageHandler(
Map<String, dynamic> message) async {
print("onLaunch: $message");
_showBigPictureNotification(message);
// Or do other work.
}
initializeFcmNotification() async {
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
var initializationSettingsAndroid =
new AndroidInitializationSettings('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("onMessage: $message");
_showBigPictureNotification(message);
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
}
/// Get the token, save it to the database for current user
_saveDeviceToken() async {
String fcmToken = await _fcm.getToken();
print("FCM_TOKEN: $fcmToken");
}
Future<void> _showBigPictureNotification(message) async {
var rng = new Random();
var notifId = rng.nextInt(100);
var largeIconPath = await _downloadAndSaveImage(
'https://cdn.pixabay.com/photo/2019/04/21/21/29/pattern-4145023_960_720.jpg',
'largeIcon');
var bigPicturePath = await _downloadAndSaveImage(
'https://cdn.pixabay.com/photo/2019/04/21/21/29/pattern-4145023_960_720.jpg',
'bigPicture');
var bigPictureStyleInformation = BigPictureStyleInformation(
bigPicturePath, BitmapSource.FilePath,
largeIcon: largeIconPath,
largeIconBitmapSource: BitmapSource.FilePath,
contentTitle: message['data']['title'],
htmlFormatContentTitle: true,
summaryText: message['data']['body'],
htmlFormatSummaryText: true);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'12', 'trading_id', message['data']['body'],
importance: Importance.High,
priority: Priority.High,
style: AndroidNotificationStyle.BigPicture,
styleInformation: bigPictureStyleInformation);
var platformChannelSpecifics =
NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
notifId,
message['data']['title'],
message['data']['body'],
platformChannelSpecifics,
payload: message['data']['body']);
}
Future<void> _showBigTextNotification(message) async {
var rng = new Random();
var notifId = rng.nextInt(100);
var bigTextStyleInformation = BigTextStyleInformation(
message['data']['body'],
htmlFormatBigText: true,
contentTitle: message['data']['title'],
htmlFormatContentTitle: true,
summaryText: message['data']['body'],
htmlFormatSummaryText: true);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'12', 'trading_id', '',
importance: Importance.High,
priority: Priority.High,
style: AndroidNotificationStyle.BigText,
styleInformation: bigTextStyleInformation);
var platformChannelSpecifics =
NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
notifId,
message['data']['title'],
message['data']['body'],
platformChannelSpecifics,
payload: message['data']['body']);
}
Future onSelectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
// await Navigator.push(
// context,
// new MaterialPageRoute(builder: (context) => new SecondScreen(payload)),
// );
}
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
}
Future<String> _downloadAndSaveImage(String url, String fileName) async {
var directory = await getApplicationDocumentsDirectory();
var filePath = '${directory.path}/$fileName';
var response = await http.get(url);
var file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
}
我已经在主屏幕中这样称呼了
@override
void initState() {
// TODO: implement initState
super.initState();
new NotificationHandler().initializeFcmNotification();
}
答案 0 :(得分:2)
从最新版本(5.15)开始,您必须在处理程序初始化期间设置以下委托:
onBackgroundMessage: myBackgroundMessageHandler
请注意,您的处理程序至少应为全局或静态,反之,您将有另一个运行时异常。
以下是FCM初始化的示例:
_firebaseMessaging.configure(
onBackgroundMessage: Theme.of(context).platform == TargetPlatform.iOS
? null
: myBackgroundMessageHandler,
onMessage: (Map<String, dynamic> message) async { },
onResume: (Map<String, dynamic> message) async { },
onLaunch: (Map<String, dynamic> message) async { },
);
和处理程序模板:
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async { return Future<void>.value(); }
官方READM.me已更新,您可以找到关于here的一些注释。
这里是PR,它提供了在Android上处理后台通知的可能性。您可以找到详细信息here。
答案 1 :(得分:1)
当我使用onBackgroundMessage时,应用出现错误或崩溃。
我对Firebase消息传递的实现
main.dart
initState(){
....
HelperClass.initFCM(some dependencies);
}
helperClass.dart
class HelperClass
{
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) {
print("_backgroundMessageHandler");
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
print("_backgroundMessageHandler data: ${data}");
}
if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
print("_backgroundMessageHandler notification: ${notification}");
}
Future<void> initFCM(...){
_firebaseMessaging.configure(
.....,
onBackgroundMessage: backgroundMessageHandler,
.....
);
}
}
我无法在main.dart上配置firebase,因为我对此有一些逻辑。例如,仅当用户登录时,我才启动FCM。因此,我必须在类中配置firebase。
启动应用程序时,ToRawHandle()出现错误
E/flutter (23610): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method 'toRawHandle' was called on null.
E/flutter (23610): Receiver: null
E/flutter (23610): Tried calling: toRawHandle()
E/flutter (23610): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter (23610): #1 FirebaseMessaging.configure
package:firebase_messaging/firebase_messaging.dart:12
当我将功能设置为 STATIC 时,
static Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) {
print("_backgroundMessageHandler");
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
print("_backgroundMessageHandler data: ${data}");
}
if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
print("_backgroundMessageHandler notification: ${notification}");
}
在配置Firebase期间APP崩溃
uid: 10532
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
x0 0000000000000000 x1 0000000000005fda x2 0000000000000006 x3 00000077dc702860
x4 00000077dc702740 x5 00000077dc702740 x6 00000077dc702740 x7 0000000000000000
x8 00000000000000f0 x9 204a59b65fcacfed x10 fffffff0fffffbdf x11 0000000000000000
x12 0000000000000000 x13 0000000000000010 x14 0000000000000020 x15 00000077dc702740
x16 00000078d0ef68b8 x17 00000078d0ed4710 x18 00000077cd1e8000 x19 00000000000000ac
x20 0000000000005f77 x21 00000000000000b2 x22 0000000000005fda x23 00000000ffffffff
x24 000000000000003a x25 00000077dc703020 x26 000000000000003a x27 0000000000000001
x28 0000000000000001 x29 00000077dc702910
sp 00000077dc702840 lr 00000078d0e8744c pc 00000078d0e8746c
backtrace:
#00 pc 000000000008246c /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) (BuildId: 5812256023147338b8a9538321d4c456)
#01 pc 00000000011c8d80 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#02 pc 00000000011d39a0 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#03 pc 00000000011d7c54 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#04 pc 00000000011cf744 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#05 pc 00000000011d5a78 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#06 pc 00000000011d6154 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#07 pc 00000000011d55b0 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#08 pc 00000000011da7c8 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#09 pc 0000000000017efc /system/lib64/libutils.so (android::Looper::pollInner(int)+864) (BuildId: 519d0734bba3d4086a9088e9bcb201de)
#10 pc 0000000000017afc /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+56) (BuildId: 519d0734bba3d4086a9088e9bcb201de)
#11 pc 0000000000013644 /system/lib64/libandroid.so (ALooper_pollOnce+96) (BuildId: 8ab9f24e53265b4640c6f4dd253b4b1f)
#12 pc 00000000011da74c /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#13 pc 00000000011d54fc /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#14 pc 00000000011d86a0 /data/app/com.kleinpetr.app-DIUNepS7D_5Cnpsb5tArzA==/lib/arm64/libflutter.so!libflutter.so (offset 0x11c0000) (BuildId: d8bf9b314511c944)
#15 pc 00000000000e372c /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36) (BuildId: 5812256023147338b8a9538321d4c456)
#16 pc 0000000000084004 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 5812256023147338b8a9538321d4c456)
Lost connection to device.
答案 2 :(得分:1)
EDIT1:
在浏览了几个git线程和stackoverflow线程后,我终于找到了最短的答案,没人能说:
“只是将手放在全球范围内”
在您的what.dart文件中,只需将_firebaseMessaging和4个处理程序,onMessage,onLaunch等……放置在本地类之外,然后就可以了!没有崩溃!
原始:
我使用了bkmza answer,但不是针对跨平台的OP修复
出于某些原因,设置
void initState() {
super.initState();
_firebaseMessaging.configure
}
无法正常工作,然后我尝试了
Future.delayed(Duration(seconds: 1), () {
_firebaseMessaging.configure
}
);
我可以完美地工作了:)
也许FCM初始化尚未准备好配置处理程序,在Firebase Core完全加载使其正常工作之后设置了延迟