Set up push notifications

Updated

Our Flutter SDK supports push notifications over FCM—including rich push messages with links and images. This page helps you add push support to your app.

How it works

If you’ve followed our getting started instructions, you’re already set up to send push notifications to your Android audience. But you’ll need to add a bit of code to support your iOS users.

Remember that a device/user can’t receive a push notification until you:

  1. (iOS) Register a device token for the device; code samples on this page help you do that.
  2. Identify a person. This associates a token with the person; you can’t send push notifications to a device until you identify the recipient.
  3. (Both iOS and Android) Check for notification permissions. If your app user doesn’t grant permission, notifications will not appear in the system tray.
  4. (Optional) Set up your app to report push metrics back to Customer.io.

 Did you already set up your push providers?

To send, test, and receive push notifications, you’ll need to set up your push notification service(s) in Customer.io. If you haven’t already, set up Firebase Cloud Messaging (FCM).

Set up push for Android

If you followed our Getting Started instructions, you’re already set up to send push notifications to Android devices. You just need to set up iOS push support in your app.

Next, you can set up deep links if you want your notifications to link into your app.

Set or change your push icon

You’ll set the icon that appears on push notifications as a part of the AndroidManifest.xml file in your app’s android folder. If your icon appears in the wrong size, or if you want to change the standard icon that appears with your push notifications, you’ll need to update your app’s manifest.

<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_notification" />
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorNotificationIcon" />

Set up push for iOS

You’ll need to add some additional code to support push notifications for iOS. You’ll need to add push capabilities in XCode and integrate push capabilities in your app.

Add push capabilities in Xcode

Before you can work with push notifications, you need to add Push Notification capabilities to your project in XCode.

  1. In your Flutter project, go to the ios subfolder and open <yourAppName>.xcworkspace.

  2. Select your project. Under Targets, select your main app.

  3. Click the Signing & Capabilities tab and click Capability.

  4. Add Push Notifications to your app.

    add push notification capabilities to your app
    add push notification capabilities to your app

  5. Select File > New > Target.

    xcode-servicenotification1.png
    xcode-servicenotification1.png
  6. Select Notification Service Extension and click Next.

    xcode-servicenotification2.png
    xcode-servicenotification2.png
  7. You should see a window such as this:

    xcode-servicenotification3.png
    xcode-servicenotification3.png

    You can leave many of the options in this window as their defaults, but you should:

    • Enter a product name, like NotificationServiceExtension (which we use in our examples on this page)
    • Confirm that your main app is selected in the Embed in Application drop-down menu

    When you’re done, click Finish.

  8. When presented with the dialog below, click Cancel. This will help Xcode continue debugging your app and not just the extension you just added.

    xcode-servicenotification4.png
    xcode-servicenotification4.png

Now you have another target in your project navigator named NotificationServiceExtension. We’ll configure this extension when we Integrate Push Notifications in the following section.

Integrate push capabilities in your app

  1. Open the file ios/Podfile and make the following modifications:

    target 'Runner' do # Look for the main app target.
      # Required by FCM push notification service 
      use_frameworks! 
    
      <!-- is this still necessary? -->
      # Make all file modifications after these lines: 
      config = use_native_modules!
    
      # Add the following line to add the Customer.io native dependency: 
      pod 'customer_io/fcm', :path => '.symlinks/plugins/customer_io/ios
    end
    
    # Next, copy and paste the code below to the bottom of your Podfile: 
    target 'NotificationServiceExtension' do
      pod 'customer_io_richpush/fcm', :path => '.symlinks/plugins/customer_io/ios'
    end
       

     Do you need to fetch updates?

    See our update guide for full instructions on how to update the Flutter SDK, including how to update the Podfile.

  2. Run pod install --repo-update --project-directory=ios from the root directory of your Flutter project. When dependencies finish installing, you should see a message like this:

    Pod installation complete! There are X dependencies from the Podfile and Y total pods installed.
    
  3. Update your AppDelegate.swift file to handle push notifications.

     import UIKit
     import Flutter
     import CioMessagingPushFCM
     import FirebaseMessaging
     import FirebaseCore
    
     @main
     @objc class AppDelegate: FlutterAppDelegate {
         override func application(
             _ application: UIApplication,
             didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
         ) -> Bool {
             GeneratedPluginRegistrant.register(with: self)
    
             // Depending on how you install Firebase, 
             // you may need to add functions to this file, like:
             // FirebaseApp.configure()
             // 
             // Read the official Firebase docs to install Firebase correctly! 
    
             Messaging.messaging().delegate = self
    
             MessagingPushFCM.initialize(
                 withConfig: MessagingPushConfigBuilder()
                     .build()
             )
    
             // This sets a 3rd party push event handler for the app—rather than the Customer.io SDK and FlutterFire.
             // Setting the AppDelegate as the handler will internally use `flutter_local_notifications` to handle push events.
             UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    
             return super.application(application, didFinishLaunchingWithOptions: launchOptions)
         }
    
         func application(application: UIApplication,
                         didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
             Messaging.messaging().setAPNSToken(deviceToken, type: .unknown);
         }
    
         override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
             MessagingPush.shared.application(application, didFailToRegisterForRemoteNotificationsWithError: error)
         }
     }
    
     extension AppDelegate: MessagingDelegate {
         func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
             MessagingPush.shared.messaging(messaging, didReceiveRegistrationToken: fcmToken)
         }
     }
    
  4. Open your NotificationService.swift file in XCode and modify it with the highlighted changes below:

     import CioMessagingPushFCM
    
     class NotificationService: UNNotificationServiceExtension {
           
       override func didReceive(_ request: UNNotificationRequest,
                               withContentHandler contentHandler:
                               @escaping (UNNotificationContent) -> Void) {
         
         MessagingPushFCM.initializeForExtension(
             withConfig: MessagingPushConfigBuilder(cdpApiKey: "YourCdpApiKey")
                 .build()
         )
    
         MessagingPush.shared.didReceive(request, withContentHandler: contentHandler)
       }
       
       override func serviceExtensionTimeWillExpire() { 
         MessagingPush.shared.serviceExtensionTimeWillExpire()
       }
    
     }

Now you can run your app on a physical device and send yourself push notifications with images and deep links to test your implementation. You’ll have to use a physical device because emulators can’t receive push notifications.

Sound in push notifications (iOS Only)

When you send a push notification to iOS devices that uses our SDK, you can opt to send the Default system sound or no sound at all. If your audience’s phone is set to vibrate, or they’ve disabled sound permissions for your app, the Default setting will cause the device to vibrate rather than playing a sound.

In most cases, you should use the Default sound setting to make sure your audience hears (or feels) your message. But, before you send sound, you should understand:

  1. Your app needs permission from your users to play sounds. This is done by your app, not our SDKs. Here’s an example from our iOS sample app showing how to request sound permissions.
  2. iOS users can go into System Settings and disable sound permissions for your app. Enabling the Default setting doesn’t guarantee that your audience hears a sound when your message is delivered!

 We don’t support custom sounds yet

If you want to send a custom sound, you’ll need to handle it on your own, outside the SDK and use a custom payload when you set up your push notifications.

Test your implementation

After you set up rich push, you should test your implementation. Below, we show the payload structure we use for iOS and Android. In general, you can use our regular rich push editor; it’s set up to send messages using the JSON structure we outline below.

If you want to fashion your own payload, you can use our custom payload.

the rich push editor
the rich push editor
{
  "message": {
    "apns": {
      "payload": {
        "aps": {
          // basic iOS message and options go here
          "mutable-content": 1,
          "alert": {
            "title": "string", //(optional) The title of the notification.
            "body": "string" //(optional) The message you want to send.
           }
        },
        "CIO": {
          "push": {
            "link": "string", //generally a deep link, i.e. my-app://... or https://yourwebsite.com/...
            "image": "string" //HTTPS URL of your image, including file extension
          }
        }
      },
      "headers": {
        // (optional) headers to send to the Apple Push Notification Service.
        "apns-priority": 10
      }
    } 
  }
}
            • body string
              The body of your push notification.
            • image string
              The URL of an HTTPS image that you want to use for your message.
            • link string
              A deep link (to a page in your app), or a link to a web page.
            • title string
              The title of your push notification.
          • alert
            string
            A simple alert message.
          • badge integer
            The number you want to display on your app’s icon. Set to 0 to remove the current badge, if any.
          • category string
            The notification’s type. This string must correspond to the identifier of one of the UNNotificationCategory objects you register at launch time.
          • content-available integer
            The background notification flag. Use 1 without an alert to perform a silent update. 0 indicates a normal push notification.
          • interruption-level string
            Indicates the importance and delivery timing of a notification.

            Accepted values:passive,active,time-sensitive,critical

          • mutable-content integer
            If you use the Customer.io SDK, you must set this value to 1 to support images and “delivered” metrics from your push notifications. When the value is 1, your notification is passed to your notification service app extension before delivery. Use your extension to modify the notification’s content.
          • relevance-score number
            A number between 0 and 1. The highest score is considered the “most relevant” and is featured in the notification summary.
          • sound
            string
            The name of a sound file in your app’s main bundle or in the Library/Sounds folder of your app’s container directory. Use “default” to play the system sound. For critical alerts, you’ll pass an object instead.
          • target-content-id string
            The identifier of the window brought forward.
          • thread-id string
            An identifier to group related notifications.
        • Custom key-value pairs* any type
          Additional properties that you've set up your app to interpret outside of the Customer.io SDK.
{
  "message": {
    "data": {
      "title": "string", //(optional) The title of the notification.
      "body": "string", //The message you want to send.
      "image": "string", //https URL to an image you want to include in the notification
      "link": "string" //Deep link in the format remote-habits://deep?message=hello&message2=world
    }
  }
}
  • message
    Required The parent object for all push payloads.
        • body_loc_arg string
          Variable string values used in place of the format specifiers in body_loc_key to localize the body text to the user’s current localization. See Formatting and Styling for more information.
        • body_loc_key string
          The key to the body string in the app’s string resources that you want to use to localize the body text to the user’s current localization. See String Resources for more information.
        • click_action string
          The action that occurs when a user taps on the notification. Launches an activity with a matching intent filter when a person taps the notification.
        • color string
          The notification’s icon color in #rrggbb format.
        • icon string
          Sets the notification icon to myicon for drawable resource myicon. If you don’t send this key, FCM displays the launcher icon from your app manifest.
        • sound string
          The sound that plays when the device receives the notification. Supports "default" or the filename of a sound resource bundled in your app. Sound files must reside in /res/raw/.
        • tag string

          Identifier to replace existing notifications in the notification drawer. If empty, each request creates a new notification.

          If you specify a tag, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.

        • title_loc_arg string
          Variable string values used in place of the format specifiers in title_loc_key to localize the title text to the user’s current localization. See Formatting and Styling for more information.
        • title_loc_key string
          The key to the title string in the app’s string resources that you want to use to localize the title text to the user’s current localization. See String Resources for more information.
      • body string
        The body of your push notification.
      • image string
        The URL of an HTTPS image that you want to use for your message.
      • link string
        A deep link (to a page in your app), or a link to a web page.
      • title string
        The title of your push notification.

Copied to clipboard!
  Contents
Current release
 2.1.1
Is this page helpful?