Welcome everyone, in this article, we will implement flutter push notification through APNs (Apple Push Notification Service) and FCM (Firebase Cloud Message), and manage messages sent using AWS SNS (Amazon Simple Notification Service).
Before we go straight, we need to understand the generalization.
Simply understand, a push notification is a server that sends a text, image, or audio message to an end-user device. In addition, push notification is a service as well as a channel for communication between the user and the application installed on the user's device in real time. Push notification requires the device to have an internet connection (Wifi / 3G / LTE / 5G, ....)
Each operating system corresponds to a different notification service because each operating system will have a different notification mechanism. For Android will use GCM's service, APNs for devices with iOS operating system.
Amazon SNS is a good solution to send notifications to mobile devices with different operating systems quickly and flexibly according to selected notification service such as GCM, APNs, ... More especially, Amazon SNS can send messages to specific devices or to many devices in bulk.
There are 3 main benefits to choosing Amazon SNS:
So what are the benefits of using Push Notification when developing a mobile app?
Enable Push Notification in Apple Developer Portal
Connect to Google Firebase
dependencies: flutter: sdk: flutter firebase_messaging: ^12.0.1 firebase_core: ^1.20.0 firebase_core_platform_interface: 4.5.1 flutter_local_notifications: ^13.0.0 flutter_apns: ^1.6.0
flutter pub get
<key>UIBackgroundModes</key> <array> <string>fetch</string> <string>remote-notification</string> </array>
if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate }
<manifes> <application> <activity> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:value="@mimap/ic_notification" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@android:color/white" /> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="default_notification_channel_id" /> </application> </manifes>
import 'package:flutter_apns/flutter_apns.dart'; @pragma('vm:entry-point) Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { print("Handling a background message: ${message.messageId}"); } class _AppState extends State<App> { @override void initState() { super.initState(); _pushNotification = defaultTargetPlatform == TargetPlatform.iOS ? APNsNotificationService() : FCMNotificationService(); _pushNotification.init(); } } } Future<dynamic> onPush(String name, RemoteMessage payload) { storage.append('$name: ${payload.notification?.title}'); final action = UNNotificationAction.getIdentifier(payload.data); if (action != null && action != UNNotificationAction.defaultIdentifier) { storage.append('Action: $action'); } return Future.value(true); } Future<dynamic> _onBackgroundMessage(RemoteMessage data) => onPush('onBackgroundMessage', data); public class FCMNotificationService extends FirebaseMessagingService { @override void init() async { await Firebase.initializeApp(); _messaging = FirebaseMessaging.instance; NotificationSettings settings = await _messaging.requestPermission( alert: true, badge: true, provisional: false, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized) { print('User granted permission'); // TODO: handle the received notifications FirebaseMessaging.onMessage.listen((RemoteMessage message) { PushNotification notification = PushNotification( title: message.notification?.title, body: message.notification?.body, ); } FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); } else { print('User declined or has not accepted permission'); } } } public class APNsNotificationService extends FirebaseMessagingService { @override void init() async { connector.configure( onLaunch: (data) => onPush('onLaunch', data), onResume: (data) => onPush('onResume', data), onMessage: (data) => onPush('onMessage', data), onBackgroundMessage: _onBackgroundMessage, ); connector.requestNotificationPermissions(); connector.token.addListener(() { print('Token ${connector.token.value}'); // Store APNs Token into AWS SNS }); connector.shouldPresent = (x) async { final remote = RemoteMessage.fromMap(x.payload); return remote.category == 'MEETING_INVITATION'; }; connector.setNotificationCategories([ UNNotificationCategory( identifier: 'MEETING_INVITATION', actions: [ UNNotificationAction( identifier: 'ACCEPT_ACTION', title: 'Accept', options: UNNotificationActionOptions.values, ), UNNotificationAction( identifier: 'DECLINE_ACTION', title: 'Decline', options: [], ), ], intentIdentifiers: [], options: UNNotificationCategoryOptions.values, ), ]); } }
{ "APNS": "{\"aps\":{\"alert\":\"Sample message for iOS endpoints\",\"sound\":\"default\"}"}", "GCM":"{ \"notification\": { \"body\": \"Sample message for Android endpoints\", \"title\":\"Test\" } }" }
Good luck and hope you enjoy this post!!!!