Привет, я использую пакет Awesome_notifications_fcm для отображения уведомлений Firebase
поэтому я отправляю уведомление из серверной части с помощью node.js
Я хочу показывать уведомление с кнопкой действия, это работает для устройства Android, но ios показывает только уведомления Это флаттер-код
class NotificationController with ChangeNotifier {
static final NotificationController _instance =
NotificationController._internal();
factory NotificationController() => _instance;
NotificationController._internal();
/// INITIALIZATION
static Future initializeRemoteNotifications() async {
final _permission = await AwesomeNotifications()
.requestPermissionToSendNotifications(permissions: [
NotificationPermission.Light,
NotificationPermission.Vibration,
NotificationPermission.Alert
]);
if (_permission) {
await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelKey: 'alerts',
channelName: 'Alerts',
channelDescription: 'Alerts',
importance: NotificationImportance.High,
channelShowBadge: true,
enableLights: true,
playSound: true,
criticalAlerts: true,
enableVibration: true,
),
],
);
await AwesomeNotificationsFcm().initialize(
onFcmSilentDataHandle: onSilentDataHandle,
onFcmTokenHandle: onFcmTokenHandle,
onNativeTokenHandle: onNativeTokenHandle,
licenseKeys: Constants.awesomeNotificationLicenceKeys,
debug: false,
);
await initializeIsolateReceivePort();
} else {
await openAppSettings();
}
}
static Future initializeNotificationListeners() async {
// Only after at least the action method is set,
//the notification events are delivered
await AwesomeNotifications().setListeners(
onActionReceivedMethod: onActionReceivedMethod,
onNotificationCreatedMethod: onNotificationCreatedMethod,
onNotificationDisplayedMethod: onNotificationDisplayedMethod,
onDismissActionReceivedMethod: onDismissActionReceivedMethod,
);
}
static Future getInitialNotificationAction() async {
final ReceivedAction? receivedAction = await AwesomeNotifications()
.getInitialNotificationAction(removeFromActionEvents: false);
if (receivedAction == null) return;
// TODO: Handle Initial Notification Action
}
static ReceivePort? receivePort;
static Future initializeIsolateReceivePort() async {
receivePort = ReceivePort('Notification action port in main isolate')
..listen(
(silentData) => onActionReceivedImplementationMethod(silentData));
IsolateNameServer.registerPortWithName(
receivePort!.sendPort, 'notification_action_port');
}
/// NOTIFICATION METHODS
/// Use this method to detect when a new notification or a schedule is created
@pragma("vm:entry-point")
static Future onNotificationCreatedMethod(
ReceivedNotification receivedNotification) async {}
/// Use this method to detect every time that a new notification is displayed
@pragma("vm:entry-point")
static Future onNotificationDisplayedMethod(
ReceivedNotification receivedNotification) async {}
/// Use this method to detect if the user dismissed a notification
@pragma("vm:entry-point")
static Future onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {}
/// Use this method to detect when the user taps on a notification
/// or action button
@pragma('vm:entry-point')
static Future onActionReceivedMethod(
ReceivedAction receivedAction) async {
if (receivedAction.buttonKeyPressed.isEmpty) {
final String? route = receivedAction.payload?['route'];
if (route == null) return;
navigate(route);
}
if (receivedAction.actionType == ActionType.SilentAction ||
receivedAction.actionType == ActionType.SilentBackgroundAction) {
// For background actions, you must hold the execution until the end
await executeLongTaskInBackground(receivedAction);
return;
} else {
if (receivePort == null) {
// onActionReceivedMethod was called inside a parallel dart isolate.
final SendPort? sendPort =
IsolateNameServer.lookupPortByName('notification_action_port');
if (sendPort != null) {
// Redirecting the execution to main isolate process (this process is
// only necessary when you need to redirect the user to a new page or
// use a valid context)
sendPort.send(receivedAction);
return;
}
}
}
return onActionReceivedImplementationMethod(receivedAction);
}
static void navigate(String route) {
Get.key.currentState?.pushNamed(route);
}
static Future onActionReceivedImplementationMethod(
ReceivedAction receivedAction) async {
AwesomeNotifications().resetGlobalBadge();
// TODO: Handle Action button
}
/// REMOTE NOTIFICATION METHODS
/// Use this method to execute on background when a silent data arrives
/// (even while terminated)
@pragma("vm:entry-point")
static Future onSilentDataHandle(FcmSilentData silentData) async {
print('Silent Data: $silentData');
// TODO: Handle Silent Data
}
/// Use this method to detect when a new fcm token is received
@pragma("vm:entry-point")
static Future onFcmTokenHandle(String fcmToken) async {
final FcmTokenUsecase fcmTokenUsecase = Get.find();
await fcmTokenUsecase.updateFcmToken(fcmToken);
}
/// Use this method to detect when a new native token is received
@pragma("vm:entry-point")
static Future onNativeTokenHandle(String token) async {}
/// Silent Background notification action
static Future executeLongTaskInBackground(
ReceivedAction receivedAction) async {
// TODO: Execute Background Task
}
/// Get FCM TOKEN
Future getFCMToken() async {
if (await AwesomeNotificationsFcm().isFirebaseAvailable) {
try {
final token = await AwesomeNotificationsFcm().requestFirebaseAppToken();
print('Fcm Token: $token');
log("Fcm Token: $token");
return token;
} catch (exception) {
debugPrint('$exception');
}
} else {
debugPrint('Firebase is not available on this project');
}
return '';
}
этому флаттер-коду не нужно писать метод создания уведомления, он автоматически показывает все в порядке.
Код Node.js
Я могу управлять содержимым уведомления и кнопкой действия или URL-адресом изображения, которое будет отправлено из серверной части, и оно будет автоматически меняться на основе json.
Привет, я использую пакет Awesome_notifications_fcm для отображения уведомлений Firebase поэтому я отправляю уведомление из серверной части с помощью node.js Я хочу показывать уведомление с кнопкой действия, это работает для устройства Android, но ios показывает только уведомления [b]Это флаттер-код[/b] [code] class NotificationController with ChangeNotifier { static final NotificationController _instance = NotificationController._internal();
static Future initializeNotificationListeners() async { // Only after at least the action method is set, //the notification events are delivered await AwesomeNotifications().setListeners( onActionReceivedMethod: onActionReceivedMethod, onNotificationCreatedMethod: onNotificationCreatedMethod, onNotificationDisplayedMethod: onNotificationDisplayedMethod, onDismissActionReceivedMethod: onDismissActionReceivedMethod, ); }
/// Use this method to detect when a new notification or a schedule is created @pragma("vm:entry-point") static Future onNotificationCreatedMethod( ReceivedNotification receivedNotification) async {}
/// Use this method to detect every time that a new notification is displayed @pragma("vm:entry-point") static Future onNotificationDisplayedMethod( ReceivedNotification receivedNotification) async {}
/// Use this method to detect if the user dismissed a notification @pragma("vm:entry-point") static Future onDismissActionReceivedMethod( ReceivedAction receivedAction) async {}
/// Use this method to detect when the user taps on a notification /// or action button @pragma('vm:entry-point') static Future onActionReceivedMethod( ReceivedAction receivedAction) async { if (receivedAction.buttonKeyPressed.isEmpty) { final String? route = receivedAction.payload?['route']; if (route == null) return; navigate(route); }
if (receivedAction.actionType == ActionType.SilentAction || receivedAction.actionType == ActionType.SilentBackgroundAction) { // For background actions, you must hold the execution until the end await executeLongTaskInBackground(receivedAction); return; } else { if (receivePort == null) { // onActionReceivedMethod was called inside a parallel dart isolate. final SendPort? sendPort = IsolateNameServer.lookupPortByName('notification_action_port');
if (sendPort != null) { // Redirecting the execution to main isolate process (this process is // only necessary when you need to redirect the user to a new page or // use a valid context) sendPort.send(receivedAction); return; } } }
/// Use this method to execute on background when a silent data arrives /// (even while terminated) @pragma("vm:entry-point") static Future onSilentDataHandle(FcmSilentData silentData) async { print('Silent Data: $silentData'); // TODO: Handle Silent Data }
/// Use this method to detect when a new fcm token is received @pragma("vm:entry-point") static Future onFcmTokenHandle(String fcmToken) async { final FcmTokenUsecase fcmTokenUsecase = Get.find();
await fcmTokenUsecase.updateFcmToken(fcmToken); }
/// Use this method to detect when a new native token is received @pragma("vm:entry-point") static Future onNativeTokenHandle(String token) async {}
/// Get FCM TOKEN Future getFCMToken() async { if (await AwesomeNotificationsFcm().isFirebaseAvailable) { try { final token = await AwesomeNotificationsFcm().requestFirebaseAppToken();
print('Fcm Token: $token'); log("Fcm Token: $token"); return token; } catch (exception) { debugPrint('$exception'); } } else { debugPrint('Firebase is not available on this project'); } return ''; } [/code] этому флаттер-коду не нужно писать метод создания уведомления, он автоматически показывает все в порядке. Код Node.js [code]const payload = { token: record.token, notification: { title: record.title, body: record.body, }, data: { role: record?.type ?? '', topic: record?.action ?? '', sub_topic: record?.title ?? '', "actionButtons.0.key": "REDIRECT", "actionButtons.0.label": "Redirect", "actionButtons.0.autoDismissible": "true", } }; console.log('Sending payload:', payload);
[/code] Я могу управлять содержимым уведомления и кнопкой действия или URL-адресом изображения, которое будет отправлено из серверной части, и оно будет автоматически меняться на основе json.