Firebase 消息传递 - 当应用程序关闭或在 Flutter 中休眠时不发送通知
Firebase messaging - Notifications are not sent when app is Closed or sleep in Flutter
我已经在 flutter 中构建了我的应用程序,并且我已经实现了 LocalNotifications 和 FCM 消息传递。
这是我的代码:
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
@override
void initState() {
super.initState();
registerNotification();
configLocalNotification();
}
void registerNotification() {
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
return ;
}, onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationsScreen()));
},
onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
});
firebaseMessaging.getToken().then((token) {
print('token: $token');
FirebaseFirestore.instance
.collection('Consultant')
.doc(firebaseUser.uid)
.update({'deviceToken': token});
}).catchError((err) {
//Fluttertoast.showToast(msg: err.message.toString());
});
}
Future selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
}
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => NotificationsScreen(payload: payload,)),
);
}
void showNotification(message) async {
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
Platform.isAndroid
? 'it.wytex.vibeland_pro_app'
: 'it.wytex.vibeland_pro_app',
'Vibeland Pro',
'Vibeland Pro',
playSound: true,
enableVibration: true,
importance: Importance.max,
priority: Priority.high,
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics);
print(message);
print(message['body'].toString());
print(json.encode(message));
await flutterLocalNotificationsPlugin.show(0, message['title'].toString(),
message['body'].toString(), platformChannelSpecifics,
payload: json.encode(message));
await flutterLocalNotificationsPlugin.show(
1, ' Hai ricevuto un messaggio ', 'Controlla subito le Tue notifiche ', platformChannelSpecifics,
payload: 'item x',
);
}
void configLocalNotification() {
var initializationSettingsAndroid =
new AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettingsIOS = new IOSInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = new InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
我在 firebase 中构建了一个函数来推送一些新集合作为通知。
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const fcm = admin.messaging();
exports.sendNotification = functions.firestore
.document("Notifications/{id}")
.onCreate((snapshot) => {
const name = snapshot.get("name");
const subject = snapshot.get("subject");
const token = snapshot.get("token");
const payload = {
notification: {
title: "" + name,
body: "" + subject,
sound: "default",
click_action: "FLUTTER_NOTIFICATION_CLICK",
},
};
return fcm.sendToDevice(token, payload);
});
firebase_messaging: ^7.0.3
和 flutter_local_notifications: ^4.0.1
的版本
目前,由于与依赖项存在一些冲突,我没有升级。
通过这种方式,当应用程序打开时我收到了两个通知,我正确地收到了本地通知,当应用程序处于前台和后台时,我根据添加到我的 firestore 中的新集合获得了 Firebasemessaging。
现在,当我关闭应用程序或几分钟后应用程序开始休眠时,问题就来了……
我收不到任何通知
要重新开始接收通知,我需要再次 运行 应用程序并唤醒应用程序。
这是我的应用程序的问题,因为我的应用程序通知非常重要,用户需要始终获取它们。
正如您在 FlutterFire documentation 上所做的那样,插件对前台和后台通知的处理方式不同,因此您需要在应用中修复两件事。
首先,您需要准备好您的 Cloud Function 来发送后台通知和前台通知,为此,您需要准备好您的 json,不仅要有 notification
,还要有还有一个data
字段,如下:
const payload = {
notification: {
title: "" + name,
body: "" + subject,
sound: "default",
},
data: {
click_action: "FLUTTER_NOTIFICATION_CLICK"
}
};
其次,您将需要配置您的 firebaseMassaging 以接收后台消息,如下所示:
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
return ;
},
onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationsScreen()));
},
onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
},
onBackgroundMessage: myBackgroundMessageHandler
);
最后,您需要创建一个手动处理后台消息的处理程序,按照文档中的示例,您可以执行如下操作:
Future<void> myBackgroundMessageHandler(RemoteMessage message) async {
print("Handling a background message: ${message}");
}
添加行:
onBackgroundMessage: myBackgroundMessageHandler
Future<void> myBackgroundMessageHandler(RemoteMessage message) async {
print("Handling a background message: ${message}");
}
我遇到了这些错误:
Nexus, [10.03.21 16:59]
[ File : app-release.apk ]
Amore, [10.03.21 17:09]
java.lang.RuntimeException: Unable to create service io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: java.lang.RuntimeException: PluginRegistrantCallback is not set.
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4023)
at android.app.ActivityThread.access00(ActivityThread.java:224)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1903)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.RuntimeException: PluginRegistrantCallback is not set.
at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.C(Unknown Source:70)
at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.onCreate(Unknown Source:40)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4011)
... 8 more
我已经在 flutter 中构建了我的应用程序,并且我已经实现了 LocalNotifications 和 FCM 消息传递。
这是我的代码:
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
@override
void initState() {
super.initState();
registerNotification();
configLocalNotification();
}
void registerNotification() {
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
return ;
}, onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationsScreen()));
},
onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
});
firebaseMessaging.getToken().then((token) {
print('token: $token');
FirebaseFirestore.instance
.collection('Consultant')
.doc(firebaseUser.uid)
.update({'deviceToken': token});
}).catchError((err) {
//Fluttertoast.showToast(msg: err.message.toString());
});
}
Future selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
}
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => NotificationsScreen(payload: payload,)),
);
}
void showNotification(message) async {
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
Platform.isAndroid
? 'it.wytex.vibeland_pro_app'
: 'it.wytex.vibeland_pro_app',
'Vibeland Pro',
'Vibeland Pro',
playSound: true,
enableVibration: true,
importance: Importance.max,
priority: Priority.high,
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics);
print(message);
print(message['body'].toString());
print(json.encode(message));
await flutterLocalNotificationsPlugin.show(0, message['title'].toString(),
message['body'].toString(), platformChannelSpecifics,
payload: json.encode(message));
await flutterLocalNotificationsPlugin.show(
1, ' Hai ricevuto un messaggio ', 'Controlla subito le Tue notifiche ', platformChannelSpecifics,
payload: 'item x',
);
}
void configLocalNotification() {
var initializationSettingsAndroid =
new AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettingsIOS = new IOSInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = new InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
我在 firebase 中构建了一个函数来推送一些新集合作为通知。
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const fcm = admin.messaging();
exports.sendNotification = functions.firestore
.document("Notifications/{id}")
.onCreate((snapshot) => {
const name = snapshot.get("name");
const subject = snapshot.get("subject");
const token = snapshot.get("token");
const payload = {
notification: {
title: "" + name,
body: "" + subject,
sound: "default",
click_action: "FLUTTER_NOTIFICATION_CLICK",
},
};
return fcm.sendToDevice(token, payload);
});
firebase_messaging: ^7.0.3
和 flutter_local_notifications: ^4.0.1
的版本
目前,由于与依赖项存在一些冲突,我没有升级。
通过这种方式,当应用程序打开时我收到了两个通知,我正确地收到了本地通知,当应用程序处于前台和后台时,我根据添加到我的 firestore 中的新集合获得了 Firebasemessaging。
现在,当我关闭应用程序或几分钟后应用程序开始休眠时,问题就来了……
我收不到任何通知
要重新开始接收通知,我需要再次 运行 应用程序并唤醒应用程序。 这是我的应用程序的问题,因为我的应用程序通知非常重要,用户需要始终获取它们。
正如您在 FlutterFire documentation 上所做的那样,插件对前台和后台通知的处理方式不同,因此您需要在应用中修复两件事。
首先,您需要准备好您的 Cloud Function 来发送后台通知和前台通知,为此,您需要准备好您的 json,不仅要有 notification
,还要有还有一个data
字段,如下:
const payload = {
notification: {
title: "" + name,
body: "" + subject,
sound: "default",
},
data: {
click_action: "FLUTTER_NOTIFICATION_CLICK"
}
};
其次,您将需要配置您的 firebaseMassaging 以接收后台消息,如下所示:
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
return ;
},
onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationsScreen()));
},
onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
},
onBackgroundMessage: myBackgroundMessageHandler
);
最后,您需要创建一个手动处理后台消息的处理程序,按照文档中的示例,您可以执行如下操作:
Future<void> myBackgroundMessageHandler(RemoteMessage message) async {
print("Handling a background message: ${message}");
}
添加行:
onBackgroundMessage: myBackgroundMessageHandler
Future<void> myBackgroundMessageHandler(RemoteMessage message) async {
print("Handling a background message: ${message}");
}
我遇到了这些错误:
Nexus, [10.03.21 16:59]
[ File : app-release.apk ]
Amore, [10.03.21 17:09]
java.lang.RuntimeException: Unable to create service io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: java.lang.RuntimeException: PluginRegistrantCallback is not set.
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4023)
at android.app.ActivityThread.access00(ActivityThread.java:224)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1903)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.RuntimeException: PluginRegistrantCallback is not set.
at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.C(Unknown Source:70)
at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.onCreate(Unknown Source:40)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4011)
... 8 more