awesome_notifications_fcm
Firebase Cloud Messaging를 통해 푸시 알림을 보내는 Awesome Notifications 확장 플러그인으로, 모든 아와이브 알림 기능을 활성화합니다.
Firebase Cloud Messaging를 통해 푸시 알림을 활성화하고 모든 애보우스 알림 기능을 제공하는 Awesome Notifications 확장 플러그인입니다.
{"sdk":"flutter"}^2.1.8^4.4.0^0.12.0{"sdk":"flutter"}아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
image
Awesome Notifications add-on to send push notifications using FCM (Firebase Cloud Messaging), with all awesome notifications features.
Exemplification of how you can send push notifications using awesome_notifications_fcm
firebase_messaging pluginThis plugin is a replacement of firebase_messaging, built specially to share and use all awesome_notifications features. Because of it, it contains all features available in firebase_messaging plugin + all awesome_notifications features.
So, you MUST not use firebase_messaging with awesome_notifications_fcm. All other Firebase plugins are compatible with awesome notification plugins.
To migrate firebase_messaging to awesome_notifications_fcm, please take a look at:
How to migrate firebase_messaging plugin.
Contributions are welcome! Please read our Contributing Guide before submitting a pull request.
Important: All pull requests must target the development branch. PRs aimed at master will be rejected.
You can make a significant difference by contributing any amount via Stripe or BuyMeACoffee. Your generous donation will primarily fund the procurement of new devices and equipment, enabling us to rigorously test and guarantee the seamless functionality of our plugins across all platforms and versions. Join us in enhancing and sustaining the quality of our work. Your support is invaluable!
Donate With Stripe Donate With Buy Me A Coffee
Stay up to date with new updates and get community support by subscribing to our Discord chat server:
Plugin Dependency: This plugin functions as an add-on of the awesome_notifications plugin and inherently depends on it.
Notification Reliability: Be mindful that like local notifications, push notifications are not guaranteed to be 100% reliable. They may be delayed or denied due to factors such as battery-saving modes, background processing restrictions, and internet connection issues. Plan your business logic accordingly.
iOS Device Restrictions: On iOS, push notifications are exclusively delivered to real devices. However, other features may be tested using simulators.
Notification Troubleshooting: To investigate issues with notifications while the app is terminated, review the device logs. Utilize LogCat in Android Studio for Android, and "Console.app" on MacOS for iOS.
App Termination: Note that if your app is forcibly closed on any platform, all subsequent notifications will not be delivered until your app is actively reopened.
In this section, you going to configure your Android and iOS project to use all features available in awesome_notifications_fcm:
Add the plugins below as dependencies in your pubspec.yaml file. By using the awesome_notifications_core plugin, the versions of all compatible dependencies are managed automatically:
# Awesome plugins
awesome_notifications_core: ^0.10.0 # use the latest version available
awesome_notifications: ^0.10.0 # use the latest version available
awesome_notifications_fcm: ^0.10.0 # use the latest version available
# Firebase plugins
firebase_core: ^X.X.X # use the latest available
# The firebase_messaging plugin is not necessary. awesome_notifications_fcm is a replacement for it
# firebase_messaging: ^X.X.X
Note: Always ensure to use the latest versions of all these plugins.
To use Awesome Notifications Fcm and receive push notifications using all awesome features, first you need to enable Firebase at your project with flutterfire_cli.
1 - Install the required command line tools
If you haven't already, install Firebase CLI.
Then you need to log into Firebase using your Google account by running the following command:
firebase login
And lastly install the FlutterFire CLI by running the following command at the root of your project:
dart pub global activate flutterfire_cli
OBS: Please, pay attention to select the correct Firebase project and set the correct Application ID/Bundle ID.
Now, your Android project is configured to use awesome_notifications_fcm. Awesome!!
1 - First, ensure you have the latest XCode and cocoapods installed, with at least Swift 5.5.7.
image
2 - Run the command pod install inside your iOS project folder.
Note: If it returns any version conflict, run pod repo update and pod update to update your local repository, and then rename or erase the file "Podfile.lock" inside your iOS folder. Lastly, try to execute the command pod install once again.
image
3 - To add pictures and buttons to iOS push notifications, it is necessary to create a Notification Target Extension using XCode. Target extensions are a type of lightweight application able to run in the background for specific tasks, in this case, to customize notifications before they are delivered.
To do this, open your Flutter project using XCode. Go to your iOS project folder and open the file Runner.xcfworkspace.
With your project opened, go to "File -> New -> Target"
image
... and chose "Notification Service Extension"
image
... and add a name to your target extension at your choice (remember to make it clear that it's related to notifications).
image
And once more, run the command pod install inside your iOS project folder.
At this moment, ensure that both targets have the same minimal deployment target and try to run your application. If you succeed up to this point, you should see a notification with a title ending with [modified].
😖 Here are some common issues that may arise at this step:
1 - My notification is being displayed, but without the title ending with [modified].
A - Your Notification Service Extension is not being called. This may happen if your NSE is not attached to your main Runner target.
Ensure that your NSE is attached to the Runner target and that both have the same minimal deployment target value.
2 - My application is not being compiled, and I got the error DT_TOOLCHAIN_DIR cannot be used to evaluate LIBRARY_SEARCH_PATHS, use TOOLCHAIN_DIR instead.
A - Your CocoaPods or Xcode is outdated. You need to update or reinstall both of them, clear your project, and build everything again. Do not set your build to the legacy version as this is not the correct solution.
3 - My application is not being compiled, and I got the error Cycle inside; building could produce unreliable results: Xcode Error.
A - You need to change the order of your build phases, moving the Embed App Extensions in front of Link Binary with Libraries. This may be necessary for some projects since Xcode 15.
4 - Now, it’s time to include the Flutter and Awesome Notifications FCM libraries in your Notification Service Extension. To achieve this, modify your "PodFile", appending the lines below at the file's end. Remember to replace the two instances of MyAppServiceExtension with the name of your service extension:
Original Podfile Configuration:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings target
end
################ Awesome Notifications pod modification 1 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_pod_build_settings(installer)
################ Awesome Notifications pod modification 1 ###################
end
################ Awesome Notifications pod modification 2 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root)
################ Awesome Notifications pod modification 2 ###################
Modified Podfile with Awesome Notifications FCM Configurations:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
################ Awesome Notifications pod modification 1 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_pod_build_settings(installer)
################ Awesome Notifications pod modification 1 ###################
end
################ Awesome Notifications pod modification 2 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root)
################ Awesome Notifications pod modification 2 ###################
################ Awesome Notifications FCM pod mod ###################
awesome_fcm_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications_fcm', 'ios', 'Scripts', 'AwesomeFcmPodFile'), '.symlinks')
require awesome_fcm_pod_file
target 'MyAppServiceExtension' do
use_frameworks!
use_modular_headers!
install_awesome_fcm_ios_pod_target File.dirname(File.realpath(__FILE__))
end
update_awesome_fcm_service_target('MyAppServiceExtension', File.dirname(File.realpath(__FILE__)), flutter_root)
################ Awesome Notifications FCM pod mod ###################
Then execute the command pod install inside your ios folder to update your target extension.
5 - With these steps, your target extension can now utilize the awesome notifications library. Inside your Target extension folder, modify the file NotificationService.swift. Replace the class UNNotificationServiceExtension with DartAwesomeServiceExtension and erase all other Notification Service content. Your final file should resemble this:
import UserNotifications
import awesome_notifications_fcm
@available(iOS 10.0, *)
class NotificationService: DartAwesomeServiceExtension {
}
6 - To ensure the app builds correctly, you must set specific build settings options for each of your app targets. In your project view, click on Runner -> Target Runner -> Build Settings...
image
... and configure the following options:
In Runner Target:
In your NotificationServiceExtension Target:
7 - Lastly, it's essential to add three capabilities to your XCode project, especially "App Groups", which allows your target extensions to share data with each other.
Run your application and search on the debug console for the application group name automatically generated by Awesome Notifications. This name is unique for each application.
image
Then, open your XCode project and navigate to Targets -> Runner -> Signing and Capabilities. Click on the "+" icon and add "App Groups", "Push Notifications", and "Background Modes", ensuring you check both "Background fetch" and "Remote notification" options.
image
Under "App Groups", add the app group name automatically generated by Awesome Notifications. This name MUST start with "group.". Add the same "App Group" capability with the same app group name on your notification target extension.
image
If you prefer using a custom name instead of the generated one, you can open each info.plist file of Runner and your NSE, and add the property AwnAppGroupName with your fixed app group name, ensuring it begins with "group.".
image
Now, your iOS project is configured to use awesome_notifications_fcm. Awesome!! (phew!)
😖 Common Issues and Solutions:
1 - Issue: My notification is being displayed, but only with the simple title and body.
Solution A: Ensure your Notification Service Extension (NSE) and main Runner target are connected via App Groups, using the same and valid App Group name starting with "group.".
Solution B: Your push content might not contain the flag "mutable_content" set to true.
Solution C: If your push notification content is invalid, it will still be displayed on iOS. In such cases, "INVALID" is set as the category by Awesome Notifications. You can filter out these notifications, but you need Apple's permission to use this filter.
2 - Issue: The notification is displayed correctly with all awesome features when the app is in the Foreground. In Background or Terminated state, nothing happens.
Solution: Utilize the "Console.app" on MacOS to track the device console in these states and read the logs to identify the problem.
3 - Issue: Tapping the notification when the app is closed causes the app to become translucent and then close itself.
Solution: This occurs because apps built with Flutter can't run on iOS in debug mode without the debugger being attached. To resolve, open your project in XCode, go to Debugger > Attach to process by PID or name, and choose Runner. The debugger will be attached as your app starts up, allowing you to debug the app being awakened by a notification action (tap).
iOS Push Notifications and IDs: iOS push notifications do not support IDs/Identifiers.
Device Restrictions: Push notifications are delivered exclusively to real devices. However, other features may be tested using simulators.
Delivery Assurance: Push notifications are invariably delivered, even amidst configuration, JSON package, or Notification Service Extension errors. In such scenarios, notifications appear in their simplest form. To mitigate this, notifications with errors are categorized as "INVALID". You can filter this category by modifying your info.plist, albeit with Apple’s permission. Learn more at com.apple.developer.usernotifications.filtering.
Setting "mutable_content": Ensure to set "mutable_content" to true. Failing to do so results in your notification bypassing the Notification Service Extension (NSE), and being delivered with only the original title and body content.
Setting "content_available": Set "content_available" to true to ensure the delivery of your silent push notification.
Badge Value Recommendations: It's advisable to set the badge value in both the notification and data sections. In cases of NSE failures, iOS reads the badge value from the notification section, while the Android FCM library requires it within the data section.
Frequency of Silent Push Notifications: Refrain from frequently sending silent push notifications as Apple may begin to restrict your device's background operation. Utilize the "Console.app" on MacOS to monitor the device's logs and ascertain any blocking.
User Inactivity: Note that your push notifications may be denied on iOS if users do not access your app for an extended period. This limitation is lifted once the user reopens your application manually.
On iOS, to use any plugin inside background actions, you will need to manually register each plugin you want. Otherwise, you will face the MissingPluginException exception. To avoid this, you need to add the following lines to the didFinishLaunchingWithOptions method in your iOS project's AppDelegate.m/AppDelegate.swift file:
import Flutter
import awesome_notifications
import shared_preferences_ios
//import all_other_plugins_that_i_need
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// This function register the desired plugins to be used within a notification background action
SwiftAwesomeNotificationsPlugin.setPluginRegistrantCallback { registry in
SwiftAwesomeNotificationsPlugin.register(
with: registry.registrar(forPlugin: "io.flutter.plugins.awesomenotifications.AwesomeNotificationsPlugin")!)
FLTSharedPreferencesPlugin.register(
with: registry.registrar(forPlugin: "io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")!)
}
// This function register the desired plugins to be used within silent push notifications
SwiftAwesomeNotificationsFcmPlugin.setPluginRegistrantCallback { registry in
SwiftAwesomeNotificationsPlugin.register(
with: registry.registrar(forPlugin: "io.flutter.plugins.awesomenotifications.AwesomeNotificationsPlugin")!)
FLTSharedPreferencesPlugin.register(
with: registry.registrar(forPlugin: "io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")!)
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
And you can check how to correctly call each plugin opening the file GeneratedPluginRegistrant.m
To send push notifications using FCM (Firebase Cloud Message) you need to have an Firebase account with Cloud Messaging enable and copy the google-services.info (iOS) and google-services.json (Android) files at correct places. Also, you need to send to Firebase the APNs certificates to enable the comunication between Firebase and Apple servers. In this section we going to explain to you how to do all of that.
First, you need to create an Firebase account and activate the Firebase service called Cloud Messaging:
Cloud Messaging and add the service into your Firebase AccountAfter activate the service, a new configuration page will be displayed. This process can be repeated and edited if necessary at any time, for all platforms that you need.
In this configuration page, set correctly your app id and, on second section, download the file called google-services.info (iOS) or google-services.json (Android). The google-services.info must be placed inside the folder "ios/Runner" folder and the google-services.json must be placed inside "android/app/src" folder.
To allow Firebase send push notifications to iOS devices, its necessary to do an extra step to create the APNs certificate.
And that's it! Now your Firebase is fully configured to send push notifications to iOS and Android.
There is two ways to send push notifications to a device:
So, to send notifications, first you need to initialize Firebase, AwesomeNotificationsFcm and them request the FCM token. Is not always possible to generate the FCM token and this process depends on Internet connection.
/// *********************************************
/// INITIALIZATION METHODS
/// *********************************************
static Future<void> initializeRemoteNotifications({
required bool debug
}) async {
await Firebase.initializeApp();
await AwesomeNotificationsFcm().initialize(
onFcmSilentDataHandle: NotificationController.mySilentDataHandle,
onFcmTokenHandle: NotificationController.myFcmTokenHandle,
onNativeTokenHandle: NotificationController.myNativeTokenHandle,
debug: debug);
}
/// *********************************************
/// REMOTE NOTIFICATION EVENTS
/// *********************************************
/// Use this method to execute on background when a silent data arrives
/// (even while terminated)
@pragma("vm:entry-point")
static Future<void> mySilentDataHandle(FcmSilentData silentData) async {
print('"SilentData": ${silentData.toString()}');
if (silentData.createdLifeCycle != NotificationLifeCycle.Foreground) {
print("bg");
} else {
print("FOREGROUND");
}
print("starting long task");
await Future.delayed(Duration(seconds: 4));
final url = Uri.parse("http://google.com");
final re = await http.get(url);
print(re.body);
print("long task done");
}
/// Use this method to detect when a new fcm token is received
@pragma("vm:entry-point")
static Future<void> myFcmTokenHandle(String token) async {
debugPrint('FCM Token:"$token"');
}
/// Use this method to detect when a new native token is received
@pragma("vm:entry-point")
static Future<void> myNativeTokenHandle(String token) async {
debugPrint('Native Token:"$token"');
}
}
To request the FCM token, you can use await to wait for token be returned by the method requestFirebaseAppToken or intercept the token with your static method myFcmTokenHandle.
// Request FCM token to Firebase
Future<String> getFirebaseMessagingToken() async {
String firebaseAppToken = '';
if (await AwesomeNotificationsFcm().isFirebaseAvailable) {
try {
firebaseAppToken = await AwesomeNotificationsFcm().requestFirebaseAppToken();
}
catch (exception){
debugPrint('$exception');
}
} else {
debugPrint('Firebase is not available on this project');
}
return firebaseAppToken;
}
Send this token to your backend server and this way you got the "device address" to send notifications. Its recommended to also send the native token to your server, as not all push services are available by Cloud Messaging.
To utilize all the features available when sending push notifications with Awesome Notifications, you can use one of the 3 standards available:
Json data standard (Legacy protocol):
{
"to" : "{{fcm_token_ios}}",
"priority": "high",
"mutable_content": true,
"notification": {
"badge": 42,
"title": "Huston! The eagle has landed!",
"body": "A small step for a man, but a giant leap to Flutter's community!"
},
"data" : {
"content": {
"id": 1,
"badge": 42,
"channelKey": "alerts",
"displayOnForeground": true,
"notificationLayout": "BigPicture",
"largeIcon": "https://br.web.img3.acsta.net/pictures/19/06/18/17/09/0834720.jpg",
"bigPicture": "https://www.dw.com/image/49519617_303.jpg",
"showWhen": true,
"autoDismissible": true,
"privacy": "Private",
"payload": {
"secret": "Awesome Notifications Rocks!"
}
},
"actionButtons": [
{
"key": "REDIRECT",
"label": "Redirect",
"autoDismissible": true
},
{
"key": "DISMISS",
"label": "Dismiss",
"actionType": "DismissAction",
"isDangerousOption": true,
"autoDismissible": true
}
],
"Android": {
"content": {
"title": "Android! The eagle has landed!",
"payload": {
"android": "android custom content!"
}
}
},
"iOS": {
"content": {
"title": "Jobs! The eagle has landed!",
"payload": {
"ios": "ios custom content!"
}
},
"actionButtons": [
{
"key": "REDIRECT",
"label": "Redirect message",
"autoDismissible": true
},
{
"key": "DISMISS",
"label": "Dismiss message",
"actionType": "DismissAction",
"isDangerousOption": true,
"autoDismissible": true
}
]
}
}
}
Stringify data standard (V1 protocol):
OBS: The expected type in data section is Map<String, String>.
{
"message": {
"token": "{{fcm_token_ios}}",
"android": {
"priority": "high"
},
"apns": {
"payload": {
"aps": {
"mutable-content": 1,
"badge": 15
},
"headers": {
"apns-priority": 5
}
}
},
"notification": {
"title": "Huston! The eagle has landed!",
"body": "A small step for a man, but a giant leap to Flutter's community!"
},
"data": {
"content": "{\"id\":-1,\"badge\":1,\"channelKey\":\"alerts\",\"displayOnForeground\":true,\"notificationLayout\":\"BigPicture\",\"largeIcon\":\"https://br.web.img3.acsta.net/pictures/19/06/18/17/09/0834720.jpg\",\"bigPicture\":\"https://www.dw.com/image/49519617_303.jpg\",\"showWhen\":true,\"autoDismissible\":true,\"privacy\":\"Private\",\"payload\":{\"category\":\"like\",\"userId\":\"oUGw1AHfmkQPDuP9DOAT1J0iQ1X2\",\"ownerId\":\"AppleBoy\",\"notifId\":\"liked_279f33c9-9c58-4099-940b-06a463a9d929\",\"pageId\":\"notifsPage\",\"gameAction\":\"\"}}",
"actionButtons": "[{\"key\":\"REDIRECT\",\"label\":\"Redirect\",\"autoDismissible\":true},{\"key\":\"CANCEL\",\"label\":\"Dismiss\",\"actionType\":\"DismissAction\",\"isDangerousOption\":true,\"autoDismissible\":true}]"
}
}
}
Flattened data standard (V1 protocol):
OBS: The expected type in data section is Map<String, String>.
{
"message": {
"token" : "{{fcm_token_ios}}",
"android": {
"priority": "high"
},
"apns": {
"payload": {
"aps": {
"mutable-content": 1,
"badge": 42
},
"headers": {
"apns-priority": "5"
}
}
},
"notification": {
"badge": 42,
"title": "Huston! The eagle has landed!",
"body": "A small step for a man, but a giant leap to Flutter's community!"
},
"data" : {
"content.id": "1",
"content.badge": "42",
"content.channelKey": "alerts",
"content.displayOnForeground": "true",
"content.notificationLayout": "BigPicture",
"content.largeIcon": "https://br.web.img3.acsta.net/pictures/19/06/18/17/09/0834720.jpg",
"content.bigPicture": "https://www.dw.com/image/49519617_303.jpg",
"content.showWhen": "true",
"content.autoDismissible": "true",
"content.privacy": "Private",
"content.payload.secret": "Awesome Notifications Rocks!",
"actionButtons.0.key": "REDIRECT",
"actionButtons.0.label": "Redirect",
"actionButtons.0.autoDismissible": "true",
"actionButtons.1.key": "DISMISS",
"actionButtons.1.label": "Dismiss",
"actionButtons.1.actionType": "DismissAction",
"actionButtons.1.isDangerousOption": "true",
"actionButtons.1.autoDismissible": "true",
"Android.content.title": "Android! The eagle has landed!",
"Android.content.payload.android": "android custom content!",
"iOS.content.title": "Jobs! The eagle has landed!",
"iOS.content.payload.ios": "iOS custom content!",
"iOS.actionButtons.0.key": "REDIRECT",
"iOS.actionButtons.0.label": "Redirect message",
"iOS.actionButtons.0.autoDismissible": "true",
"iOS.actionButtons.1.key": "DISMISS",
"iOS.actionButtons.1.label": "Dismiss message",
"iOS.actionButtons.1.actionType": "DismissAction",
"iOS.actionButtons.1.isDangerousOption": "true",
"iOS.actionButtons.1.autoDismissible": "true"
}
}
}
To send FCM V1 push notifications using Postman, you gonna need to request a valid bearer token using OAuth 2.0 Playground:
To send notifications using the Firebase cloud message console, you basically need to send the flattened data standard via data section:
AwesomeNotificationsFcm().requestFirebaseAppToken();.now or define a future time greater than 10 seconds from now.image
TIP: After edit all fields, save as a Draft and reopen again for edition. Then go back to step 1 and send a test message with all features available.
To send silent push notifications, avoid using the "notification" section. Use "content_available" instead of "mutable_content":
{
"message": {
"token": "{{fcm_token_ios}}",
"apns": {
"payload": {
"aps": {
"content-available": 1
}
}
},
"data": {
"data1": "fb787aa2-6387-4f65-a5a2-125f96ab4c14",
"data2": "call_voice",
"data3": "3c3079b7-ab5e-48a5-8c61-b64ebb4910a9",
"data4": "5469846578"
}
}
}
You can remotely control your app's notifications using RPC (Remote Procedure Calls). This feature allows you to dismiss notifications, cancel scheduled notifications, or cancel notifications entirely. Below are the instructions and the distinctions between each action:
Use the following JSON structure to send commands:
{
"message": {
"token": "{{fcm_token_android}}",
"apns": {
"payload": {
"aps": {
"content-available": 1
}
}
},
"data": {
"dismiss": "1,2,42",
"dismissByChannel": "channel1,channel_voice",
"dismissByGroup": "group1,group2",
"dismissAll": "true",
"cancelSchedule": "1,2,42",
"cancelScheduleByChannel": "channel1,channel_voice",
"cancelScheduleByGroup": "group1,group2",
"cancelAllSchedules": "true",
"cancelNotification": "1,2,42",
"cancelNotificationByChannel": "channel1,channel_voice",
"cancelNotificationByGroup": "group1,group2",
"cancelAllNotifications": "true",
"dontCallFlutter": "true"
}
}
}
Dismiss Notifications:
dismiss: Dismiss specific notifications by ID.dismissByChannel: Dismiss notifications by channel.dismissByGroup: Dismiss notifications by group.dismissAll: Dismiss all notifications.Cancel Scheduled Notifications:
cancelSchedule: Cancel specific scheduled notifications by ID.cancelScheduleByChannel: Cancel scheduled notifications by channel.cancelScheduleByGroup: Cancel scheduled notifications by group.cancelAllSchedules: Cancel all scheduled notifications.Cancel Notifications (Including Schedules):
cancelNotification: Cancel specific notifications and their schedules by ID.cancelNotificationByChannel: Cancel notifications and their schedules by channel.cancelNotificationByGroup: Cancel notifications and their schedules by group.cancelAllNotifications: Cancel all notifications and their schedules.dontCallFlutter to true.By using these RPC commands, you can effectively manage the notification lifecycle in your application, ensuring a seamless user experience.
You don't need a real server to send push notifications during the development stage. Use REST programs like Postman to emulate your backend for sending push notifications.
Download and import the Postman projects/collections below into your Postman. Make sure to replace the collection variables according to your Firebase project keys and your devices' tokens:
V1 FMC Examples.postman_collection.json
Legacy FMC Examples.postman_collection.json
Note: To use the V1 protocol on Postman, you'll need to generate a fresh token using the Google Developers OAuth 2.0 Playground. To generate it, follow the steps bellow:
Authorize APIs:
Login and Grant Access:
Exchange Authorization Code:
Refresh and Copy Access Token:
By following these steps, you ensure that your Postman is configured with a valid access token for sending notifications using the V1 protocol.
firebase_messaging PluginMigrating from firebase_messaging requires you to replace Firebase methods with their equivalents in Awesome Notifications and Awesome Notifications FCM:
FirebaseMessaging.onMessageOpenedApp -> AwesomeNotifications.getInitialNotificationAction()FirebaseMessaging.onMessage -> static Future<void> onActionReceivedMethod(ReceivedAction receivedAction)FirebaseMessaging.onBackgroundMessage -> static Future<void> mySilentDataHandle(FcmSilentData silentData)FirebaseMessaging.requestPermission -> AwesomeNotifications().requestPermissionToSendNotifications()To access non-static resources inside static methods, consider using design patterns such as Singleton classes or defining a Static Flutter Navigator Key in the MaterialApp widget.
To switch the execution from a background isolate to the main isolate of your application (where you have a valid context to redirect users), use the ReceivePort and SendPort classes. Below is a basic example:
import 'dart:isolate';
static ReceivePort? receivePort;
static Future<void> initializeIsolateReceivePort() async {
receivePort = ReceivePort('Silent action port in main isolate')
..listen((silentData) => mySilentDataHandle(silentData));
// This initialization only happens on main isolate
IsolateNameServer.registerPortWithName(
receivePort!.sendPort, 'silent_action_port');
}
@pragma('vm:entry-point')
void mySilentDataHandle(FcmSilentData silentData) {
// this process is only necessary when you need to have access to features
// only available if you have a valid context. Since parallel isolates do not
// have valid context, you need redirect the execution to main isolate.
if (receivePort == null) {
print(
'onActionReceivedMethod was called inside a parallel dart isolate.');
SendPort? sendPort =
IsolateNameServer.lookupPortByName('silent_action_port');
if (sendPort != null) {
print('Redirecting the execution to main isolate process.');
sendPort.send(receivedAction);
return;
}
}
// Execute the rest of your code
}
In this example, mySilentDataHandle function is responsible for creating a ReceivePort, spawning a new isolate, and listening for messages from the new isolate. The handleData function in the new isolate sends a message back to the main isolate through the SendPort.
Following these steps will ensure a smooth transition from firebase_messaging to using Awesome Notifications for managing your push notifications.