Push Notifications for Flutter apps

By now, you would have already integrated Apptics if you are using any other module. If not, refer to the integration guide.

iOS setup

  • Import and initialize in a notification service extension.
  • Specify the pod 'AppticsNotificationServiceExtension' in your podfile.
  • The podfile will look something similar to the one below.
Copied# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'AppticsPushNotificationApp', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'AppticsPushNotificationApp' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end

Note: Pass the common app group identifier --app-group-identifier="group.MAIN_BUNDLE_IDENTIFIER.apptics" to the run script as mentioned in the above sample podfile.

  • From your terminal, navigate to the iOS folder and run pod install --repo-update.
  • Open the .xcworkspace file in Xcode.
  • Go to your root project in Xcode and select the main app target. Navigate to the Signing & Capabilities tab.
  • If push notifications are not enabled, click + Capability and add push notifications.

  • Click + Capability again and add Background modes.
  • Also, enable the remote notifications.

Add notification service extension

The AppticsNotificationServiceExtension enables your iOS app to receive the rich notifications with images, buttons, and badges. It is also essential for Apptics' confirmed devliery analytics stats.

  • In Xcode, navigate to File > New > Target.
  • Select the Notification Service Extension and click Next.

  • Give a name to the NotificationServiceExtension and click Finish.

  • When prompted to activate the scheme after selecting Finish, click Cancel to avoid activating it.

  • In Xcode, select the NotificationServiceExtension target.
  • Go to general settings. Set the minimum deployment to match your main application target. This should be iOS 14.5 or higher.

Add app groups

App groups enable your app and the NotificationServiceExtension to share data when a notification is received, even if the app is not running. This is essential for implementing the badges and confirmed deliveries.

  • Select your main app target in Xcode.
  • Go to Signing & Capabilities and click on + Capability.
  • Choose App groups.

  • Click on + to add a new group.
  • Set the app groups container name to 'group.MAIN_BUNDLE_IDENTIFIER.apptics', where the MAIN_BUNDLE_IDENTIFIER should match the bundle identifier of your main application.

  • Click OK to save the app group for your main app target. Repeat the steps for the NotificationServiceExtension Target.
  • Select the NotificationServiceExtension Target > Signing & Capabilities > + Capability > App groups.

  • In app groups, click + button to add a new group.
  • Set the app group container to 'group.MAIN_BUNDLE_IDENTIFIER.apptics', making sure NOT to include 'NotificationServiceExtension' in the name.
  • Replace the MAIN_BUNDLE_IDENTIFIER with the bundle identifier of your main application.

Integrate the notification service extension

  • In the Xcode project navigator, select the NotificationServiceExtension folder.
  • Locate and open the NotificatioService.m (for Obj-C) or NotificationService.swift (for Swift) file.
  • Replace the whole content of the file with the following code.
CopiedObjective CSwift
#import "NotificationService.h"
#import <AppticsNotificationServiceExtension/AppticsNotificationServiceExtension.h>

@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end

@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    // Modify the notification content here...
    APPushNotificationExtension *apext = [APPushNotificationExtension new];
    apext.appGroup = @"group.MAIN_BUNDLE_IDENTIFIER.apptics";
        if ([apext isNotificationFromApptics:request]){
        NSLog(@"AdditionalPayload : %@", [apext getAdditionalPayload]);
        [apext didReceiveNotificationExtensionWithContent:self.bestAttemptContent contentHandler:contentHandler];
    }else{
        self.contentHandler(self.bestAttemptContent);
    }
}

- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    self.contentHandler(self.bestAttemptContent);
}
@end

Upload p12 certificate

Refer to this link for detailed steps on how to upload your p12 certificate to Apptics

Android setup

Make sure that you have configured the Firebase credentials in the Apptics web console. Refer to this link.

  • Add the push notification messaging service entry to your app’s manifest file located at android/app/src/main/AndroidManifest.xml.
Copied<application>
	<service android:name="com.zoho.apptics.pns.AppticsMessagingService"
            android:stopWithTask="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
 	</service>
</application>

Initialization

Define background handlers

  • Create top-level function for handling background events.
Copied@pragma('vm:entry-point')
Future<void> _appticsOnMessageReceived(Map<String, dynamic> message) async {
  print("Background message received: $message");
  // Handle background message
}

Register background handlers

  • In your main() function, regitser the background handlers.
Copiedvoid main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Register background handlers
  AppticsPushNotification.setOnMessageHandlerListener(_appticsOnMessageReceived);

  runApp(const MyApp());
}

Initialize push notifications

Initialize the push notification system with foreground handlers.

CopiedFuture<void> initializePushNotifications() async {
  await AppticsPushNotification.initialize(
    onMessageReceived: (Map<String, dynamic> message) {
      print("Foreground message received: $message");
      // Handle foreground message
    },
    onNotificationClick: (String? clickAction, String? payload) {
      print("Foreground notification clicked: $clickAction, $payload");
      // Handle foreground notification click
    },
    onNotificationActionClick: (String actionId, String? clickAction, String? payload) {
      print("Foreground notification action clicked: $actionId, $clickAction, $payload");
      // Handle foreground notification action click
    },
  );
}

Android notification customizations

Notification channel

Starting from Android 8 (Oreo) and above, apps must assign a notification channel for every notification. You can configure the notification channel for push notifications sent by Apptics through the Notification Builder in Apptics web console when publishing a notification.

You can also configure a default channel ID as meta-data in your AndroidManifest.xml, which will be used if no notification channel is specified in the Notification Builder.

Copied<application>
	<meta-data android:name="apptics_default_notification_channel_id" android:value="general" />
</application>

Apptics SDK posts notification with a built-in channel if no channel ID is configured.

Notification icon

Notification icon (small) can be configured from the Apptics web console when publishing a notification.

You can also configure a default icon as the meta-data in your AndroidManifest.xml which will be used if notification icon is not available in the incoming message.

Copied<application>
	<meta-data android:name="apptics_default_notification_icon" android:resource="@drawable/small_notif_icon" />
</application>

If both the default icon and icon from the incoming messages are not available, App icon will be used.

Notification color

Notification color can be configured from the Apptics web console when publishing a notification.

You can also configure a default color as the meta-data in your AndroidManifest.xml which will be used if the color is not available in the incoming message.

Copied<application>
	<meta-data android:name="apptics_default_notification_color" android:resource="@color/notif_accent" />
</application>

Notification sound

From Android 8 (Oreo) and above, notification sounds are based on the notification channels. Apptics doesn't provide any default notification channels. Refer to Notification channels to assign channels to notifications sent by Apptics.

For Android 7 and below, you can configure the notification sound from the Apptics web console while publishing the notification.

Add your custom sound file in res/raw folder and provide the name of the file with extension in additional info while publishing notification.

Note:  .3gp, .mp4, .wav are some of the supported container formats.

Event types

Message received events

  • Triggered when a push notification message is received.
Copiedvoid onMessageReceived(Map<String, dynamic> message) {
  // message contains the notification payload
  // Available in both foreground and background
}

Notification click events

  • Triggered when a user taps on a notification.
Copiedvoid onNotificationClick(String? clickAction, String? payload) {
  // clickAction: Custom action defined in the notification
  // payload: Additional data sent with the notification
}

Notification action click events

  • Triggered when a user taps on a notification action button.
Copiedvoid onNotificationActionClick(String actionId, String? clickAction, String? payload) {
  // actionId: ID of the action button that was clicked
  // clickAction: Custom action defined for the action button
  // payload: Additional data sent with the notification
}