Integrate your app

Before you can send push notifications, you need to set up your workspace to send push notifications through your push provider and configure your app to receive push notifications. You can do this with or without our SDKs providing flexibility in how you send and receive push notifications.

When you integrate with us, you have some choices depending on the push platform you use (APNs, FCM) and whether or not you want to use our SDKs—though we strongly recommend that you use our SDKs if possible to simplify your integration process.

But, before you can send and receive push notifications with Customer.io, you must:

  1. Generate and add certificates for your push service, Apple Push Notification service (APNs) and/or Firebase Cloud Messaging (FCM).

  2. Configure push in your app. You can do this with our SDKs or integrate directly with our API. Our SDKs provide a ready-made interface to configure push. If you want to integrate Customer.io without using our SDKs, you’ll need to write your own code to:

    • Identify people and set their device token
    • Send events representing your users’ actions back to Customer.io
  3. Send yourself a push notification to test your implementation.

Generate and add push certificates

Before you can send a push notification, you need to generate certificates from Apple’s push notification service (APNs) and/or Google’s Firebase Cloud Messaging service (FCM) and add them to your workspace. This authorizes Customer.io to send notifications to your app through your push provider(s).

Firebase Cloud Messaging (FCM) setup

You can send notifications to Android and iOS devices through Firebase Cloud Messaging. You’ll need to generate a JSON server key, which you upload to Customer.io, granting us the ability to send push notifications.

  1. Make sure that the Firebase Cloud Messaging API is enabled for your project. You can check that here.

  2. Log into the Firebase Console for your project.

  3. Click in the sidebar and go to Project settings.

    Access your project settings in firebase
    Access your project settings in firebase

  4. Go to the Service Accounts tab and click Generate New Private Key. Confirm your choice and download the credential file.

    Generate a new private key in Firebase
    Generate a new private key in Firebase

  5. In Customer.io, go to your workspace’s Settings > Workspace Settings and click Settings next to Push.

  6. For Android, click Enable, and then click Choose file… to select the JSON server key you generated in previous steps. When you’re done, your workspace is setup to send notifications through Firebase to Android devices.

    image.png
    image.png

Send to iOS via Firebase

After you’ve set up Firebase for Android, you can enable Firebase as your iOS push-provider.

  1. In Customer.io, go to Settings > Workspace Settings and click Settings next to Push.

  2. For iOS, click Enable, and select the Firebase Cloud Messaging (FCM) option.

Push Settings - iOS_provider (FCM)
Push Settings - iOS_provider (FCM)

Apple Push Notification service (APNs) setup

You can send push notifications to iOS devices using the Apple Push Notification service (APNs).

To authorize your Customer.io workspace to send notifications to iOS devices over Apple’s Push Notification service, you’ll need to upload your APNs .p8 certificate and enter your Apple Developer Key ID, Team ID, and Bundle ID.

  1. In Customer.io, go to your workspace’s Settings > Workspace Settings and click Settings next to Push.

  2. Click Enable under iOS, and select the Apple Push Notification service (APNs) option.

  3. Click Choose file… and upload your .p8 certificate.

  4. Enter your Key ID, Team ID, and Bundle ID. You can find these in your Apple Developer Account.

  5. (Optional) Enable the Send all push notifications to sandbox option.

    Your iOS certificate may have both sandbox and production environments; this option sends push notifications to both environments.

    image.png
    image.png

     We recommend creating a separate workspace for your sandbox environment.

  6. Click Save Changes

Push Settings - iOS_provider (APNs)
Push Settings - iOS_provider (APNs)

Configure push without our SDKs

In general, we suggest that you integrate using our SDKs, which provide ready-made methods to interpret messages, identify devices, and send client-side events.

However, if you want to write your own integration with Customer.io, we’ve provided some code samples below to help you get started with push notifications. You’ll need to familiarize yourself with your integration platform to understand the range of configuration options that you have available.

If your mobile app is already set up to receive push notifications, you won’t need to make many changes to work with Customer.io. But, you should be aware that we send two custom parameters in the payload of push notification: CIO-Delivery-ID & CIO-Delivery-Token. These are used for sending Open events back to us.

iOS App Setup

The following shows an example to help you register for remote notifications in iOS.

  1. Open the project editor, and go to the Signing & Capabilities tab.

    push notification capabilities tab
    push notification capabilities tab

  2. Click Capability and and select Push Notifications.

    Select the push notification option
    Select the push notification option

  3. Update the didFinishLaunchingWithOptions callback in the AppDelegate.swift to request the device token.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Configure user interactions
        self.configureUserInteractions()
    
        // Register with APNs: this might change based on iOS versions you want to support
        UIApplication.shared.registerForRemoteNotifications()
    
        return true
    }
    
  4. Add the following methods to handle the behavior when the token request succeeds or fails.

    // Handle remote notification registration.
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        self.enableRemoteNotificationFeatures()
        // Convert token to string
        let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
        // Forward the token to your provider, using a custom method.
        self.forwardTokenToServer(token: deviceTokenString)
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        // The token is not currently available.
        print("Remote notification support is unavailable due to error: \(error.localizedDescription)")
        self.disableRemoteNotificationFeatures()
    }
    
  5. Handle the notification.

    // Push notification received
    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {  
        // Print notification payload data
        print("Push notification received: \(data)")
    
        // Customer.io push notifications include data regarding the push
        // message in the data part of the payload which can be used to send
        // feedback into our system.
        var deliveryID: String = "";
        if let value = data["CIO-Delivery-ID"] {
            deliveryID = String(describing: value)
        }
        var deliveryToken: String = "";
        if let value = data["CIO-Delivery-Token"] {
            deliveryToken = String(describing: value)
        }
    }
    

Android App Setup

The following shows an example of how to register with Firebase in Android. The easiest way to integrate Firebase Cloud Messaging into your Android app is to use the Firebase Assistant Tool in Android Studio. It walks you through the required steps.

  1. Add the Firebase SDK as a dependency into your build.gradle file.

    compile 'com.google.firebase:firebase-messaging:12.0.1'
    
  2. Create a new service that extends the FirebaseInstanceIdService class. Within this class you need a onTokenRefresh function in which you can use FirebaseInstanceId.getInstance().getToken() to retrieve the device message token.

    Note that this function is only called when the device token changes, so if you need access to it at other activities you may want to save it in a variable for later use.

    public class FirebaseIdentifierService extends FirebaseInstanceIdService {
        public FirebaseIdentifierService() {
        }
    
        @Override
        public void onTokenRefresh() {
            // Get updated InstanceID token.
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d("firebase", "Refreshed token: " + refreshedToken);
        }
    }
    
  3. Update the AndroidManifest.xml to add the service.

    <service
        android:name=".FirebaseIdentifierService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
    
  4. Now that you can generate tokens, you can handle incoming messages. Create a new service, extending FirebaseMessagingService, to handle messages.

    public class NotifierService extends FirebaseMessagingService {
        private static final String TAG = "messaging";
    
        public NotifierService() {
        }
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            // Check if message contains a data payload.
            // You can have data only notifications.
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
    
                // Customer.io push notifications include data regarding the push
                // message in the data part of the payload which can be used to send
                // feedback into our system.
                String deliveryId = remoteMessage.getData().get("CIO-Delivery-ID");
                String deliveryToken = remoteMessage.getData().get("CIO-Delivery-Token");
            }
    
            // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {    
                handleNotification(remoteMessage.getNotification());
            }
        }
    
        private void handleNotification(RemoteMessage.Notification notification) {
            Log.d(TAG, "Message Notification Body: " + notification.getBody());
        }
    }
    
  5. Update the AndroidManifest.xml one more time to add the new service.

    <service
        android:name=".NotifierService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>
    

Identify Device Tokens

Before you can send a push notification, you need to identify the person—and their device—using your app. Typically, you should send this information every time someone launches your app on their client device.

We recommend that you make calls using one of our client libraries from your backend system rather than directly from your app. If you can’t do this, and you need to make calls from within your app, you’ll want to make sure that they run asynchronously.

To add a device to the customer profile, call the following endpoint. If your account is in the EU region, make sure you use https://track-eu.customer.io

Method:  PUT
URL:     https://track.customer.io/api/v1/customers/{customer_id}/devices
JSON Payload: 
{
    "device": {
        "id": "messaging token",
        "platform": "ios/android",
        "last_used": UNIX timestamp when the device was used
    }
}

 We only store the last 25 devices

If you add a 26th device, we’ll remove the device with the oldest last_used timestamp.

You can remove a device from a person’s profile with the following request. A person can have up to 25 devices, but you should prune device tokens when…

Method:  DELETE
URL:     https://track.customer.io/api/v1/customers/{customer_id}/devices/{token}

Push payloads sent from Customer.io

We have a simple user interface for sending push notifications, including images and links. However, if you want to use our UI, you should either:

  • Integrate with our SDK(s)
  • Write your own integration, expecting to handle payloads in the following format.
The simple push editor provides all features supported by our SDK
The simple push editor provides all features supported by our SDK

If your app is already set up to receive push notifications in different formats, you can send a custom push payload instead.

Your Image URL and Deep link or web URL go inside a CIO.push object. Custom Data resides in the payload but outside the CIO and aps objects.

{
    "CIO": {
        "push": {
            "link": "string",
            "image": "string"
        }
    },
    "aps": {
        "alert": {
            "title": "Title of your push goes here!",
            "body": "Body of your push goes here!"
        },
        "sound": "default"
    }, 
    //custom keys go here
    "customKey": "a custom key"
}

The CIO.push object contains the link and image fields from notification. Custom Data resides in the payload but outside the CIO and aps objects.

{
  "message": {
    "apns": {
      "payload": {
        "CIO": {
          "push": {
            "link": "string", 
            "image": "string" 
          }
        },
        "aps": {
          "alert": {
            "title": "string", 
            "body": "string"
          },
          "sound": "default"
        },
        // custom keys go in the payload but outside the CIO and aps objects
        "customKey1": "custom keys",
        "customKey2": "another custom key"
      }
    }
  }
}

For a basic push, the push title and body reside in the message.notification. If you add an image, link, or custom data, we move the entire payload moves under the message.data object.

{
    "message": {
        "notification": {
            "title": "string", //(optional) The title of the notification
            "body": "string", //The message you want to send
        }
    }
}

For a basic push, the push title and body reside in the message.notification object—similar to Firebase’s standard notification payload. If you add an image or link, the entire payload moves under the message.data object.

{
    "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
           // other "custom keys" are sent inside this object
        }
    }
}

Send events for key customer actions

You can send events representing your audience’s activities in your app. When you send an event, you’ll set the name of the event: this is how you’ll find your event when creating segmentsA group of people who match a series of conditions. People enter and exit the segment automatically when they match or stop matching conditions. or campaignsA series of actions that you perform for each person who matches criteria. Campaigns typically send people a series of messages, but you can also use campaigns to send webhooks, update attributes, etc..

You can also send “screen view” events, representing the screens that your audience visits in your app, by sending your event with "type": "screen" and the name set to the title of the screen the person viewed. See screen view events for more information.

The example below requires you to have identified someone. The identifier in the request is either an email address or an ID, associating the event payload with that person. But you can also send anonymous events.

Method:  POST
URL:     https://track.customer.io/api/v1/customers/{identifier}/events
JSON Payload: 
{
    "name": "set favorites",
    "timestamp": 1638393518,
    "data": {
        "fav-food": "pizza"
    }
}

 We track push metrics using a different endpoint

To report push opened, converted, and delivered metrics for a specific push notification, see push opened events.

Screen view events

When you send an event, you can set the type to screen to track the pages in your app that your audience uses. This lets you create segments or tailor campaigns to people who take advantage of specific parts of your app.

When you send a screen view event, the name should be the name of the screen a person viewed. You can also send additional data in the event—an object containing properties that you may want to reference using liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable {{customer.first_name}}. in your campaigns.

The example below requires you to have identified someone. The identifier in the request is either an email address or an ID, associating the event payload with that person. But you can also send anonymous events.

Method:  POST
URL:     https://track.customer.io/api/v1/customers/{identifier}/events
JSON Payload: 
{
    "name": "mlb-scores",
    "type": "screen",
    "timestamp": 1638393518,
    "data": {
        "fav-team": "giants"
    }
}

Track push opened metrics

You can report three metrics from the client side to help track the performance of your push notifications: delivered, opened, and converted.

If you use our iOS or Android SDK, we can automatically track delivered and opened metrics for you.

Otherwise, you’ll need to send requests to the /api/v1/push/events endpoint to report metrics back to Customer.io.

When we deliver a push notification, we include CIO-Delivery-ID and CIO-Delivery-Token properties. You must include these properties in your delivered, opened, or converted events to tell us which message corresponds to the metric you’re reporting.

Metric events use a different endpoint from other types of events. To track a push open event, your request should look similar to the example below. If your account is in the EU region, make sure you use the https://track-eu.customer.io/ domain instead.

Method:  POST
URL:     https://track.customer.io/api/v1/push/events
JSON Payload: 
{
    "delivery_id": "CIO-Delivery-ID from the notification",
    "event": "opened",
    "device_id": "CIO-Delivery-Token from the notification",
    "timestamp": UNIX timestamp when the event occurred
}

Send yourself a test notification

Verify that you’ve configured everything correctly by sending yourself a test push notification. There are a couple of ways to make sure that your initial configuration is working. You can send a single test message from the settings, or (if you have an iOS app) use a separate sandbox environment for your tests.

You can send yourself a test push from the Push Notification Settings page after you’ve uploaded your certificate(s).

image.png
image.png

Enter your device token. and you’ll hopefully get a test push to that device with the following content: “If you’re reading this, it means your integration with Customer.io is working!” and you’re ready to start adding push notifications to your campaigns.

You can find your device token on the People page; click the person you want to send a test message to and go to the Devices tab.

image.png
image.png
Copied to clipboard!
  Contents
Is this page helpful?