# Push notifications

Get started setting up push notifications for Android. Our Android SDK supports push notifications over FCM, including rich push messages with links and images.

## Before you begin[](#before-you-begin)

This page explains how to receive rich push notifications using our SDK. However, before you can send push notifications to your audience, you need to enable Customer.io to send push notifications through [Firebase Cloud Messaging (FCM)](/journeys/push-getting-started/#for-android).

### How it works[](#how-it-works)

Before a device can receive a push notification, you must:

1.  Set up [FCM](/journeys/push-getting-started/#for-android).
2.  [Set up push](#set-up-push).
3.  [Identify a person](/integrations/sdk/android/identify). When someone starts the app, they automatically generate a device token. Identifying the person associates the device token with the person in Customer.io, so that they can receive push notifications.
4.  Set up a campaign to send a push notification through the Customer.io composer.

## Set up push[](#set-up-push)

1.  You must implement the Push Messaging SDK to use push notification features.
    
    ```groovy
    implementation 'io.customer.android:messaging-push-fcm:'
    ```
    
2.  Initialize the push module. The push module has an [optional config object](#push-module-config), explained below. See [deep links](#deep-links) for help configuring links.
    
    ```kotlin
     val builder = CustomerIOConfigBuilder(
         applicationContext = this,
         cdpApiKey = "your-cdp-api-key"
     ).autoTrackActivityScreens(true)
         .addCustomerIOModule(
             ModuleMessagingPushFCM()
         )
         .region(Region.US)
     
     CustomerIO.initialize(builder.build())
    ```
    

The SDK adds a `FirebaseMessagingService` to the app manifest automatically, so you don’t have to perform additional setup to handle incoming push messages.

However, if your application implements its own `FirebaseMessagingService`, make sure that when you call `onMessageReceived` and `onNewToken` methods, you also call `CustomerIOFirebaseMessagingService.onMessageReceived` and `CustomerIOFirebaseMessagingService.onNewToken` respectively.

```kotlin
class FirebaseMessagingService : FirebaseMessagingService() {

 override fun onMessageReceived(message: RemoteMessage) {
    val handled = CustomerIOFirebaseMessagingService.onMessageReceived(context, message)
    if (handled) {
        logger.breadcrumb(this, "Push notification has been handled", null)
    }
 }
 
override fun onNewToken(token: String) {
    CustomerIOFirebaseMessagingService.onNewToken(context, token)
}
```

Push notifications launched from the SDK are currently posted to our default channel—`[your app name] Channel`. In the future, we plan to let you customize channels/categories so that users can subscribe and unsubscribe to content categories as necessary.

### Push module configuration[](#push-module-config)

`ModuleMesagingPushFCM` has an optional configuration object. In most cases, our default configuration works, but you can pass the configuration object to customize the way you handle push notifications and so on.

Config option

Default

Description

`notificationCallback`

`null`

A callback that notifies the client on push notification related actions. This lets you override the default behavior for push notifications.

`autoTrackPushEvents`

`true`

Boolean: when true, the SDK automatically tracks push events like `delivered` and `opened`.

`pushClickBehavior`

`ACTIVITY_RESTART`

Lets you customize the behavior when a user taps a push notification. See [push click behavior](#push-click-behavior).

```kotlin
val builder = CustomerIOConfigBuilder(
    applicationContext = this,
    cdpApiKey = "your-cdp-api-key",
).autoTrackActivityScreens(true)
    .addCustomerIOModule(
        ModuleMessagingPushFCM(
            moduleConfig = MessagingPushModuleConfig.Builder().apply {
                setNotificationCallback(this)
            }.build()
        )
    )
    .region(Region.US)

CustomerIO.initialize(builder.build())
```

### Push click behavior[](#push-click-behavior)

The `pushClickBehavior` config lets you customize your application’s response when your audience taps a push notification. This includes going to specific deep links or launcher screens based on the notification payload. Note that the SDK tracks `opened` metrics for all click behaviors.

```kotlin
builder.addCustomerIOModule(
  ModuleMessagingPushFCM(
    moduleConfig = MessagingPushModuleConfig.Builder().apply {
      setPushClickBehavior(PushClickBehavior.ACTIVITY_PREVENT_RESTART)
    }.build()
  )
)
```

The available options are:

*   `ACTIVITY_PREVENT_RESTART` **(Default)**: If your app is already in the foreground, the SDK will not re-create your app when your audience clicks a push notification. Instead, the SDK will reuse the existing activity. If your app *is not* in the foreground, we’ll launch a new instance of your deep-linked activity. We recommend that you use this setting if your app has screens that your audience shouldn’t navigate away from—like a shopping cart screen.
    
*   `ACTIVITY_NO_FLAGS`: If your app is in the foreground, the SDK will re-create your app when your audience clicks a notification. The activity is added on top of the app’s existing navigation stack, so if your audience tries to go back, they will go back to where they previously were.
    
*   `RESET_TASK_STACK`: No matter what state your app is in (foreground, background, killed), the SDK will re-create your app when your audience clicks a push notification. Whether your app is in the foreground or background, the state of your app will be killed so your audience cannot go back to the previous screen if they press the back button.
    

## Capture push metrics[](#capture-push-metrics)

Customer.io supports device-side metrics that help you determine the efficacy of your push notifications: `delivered` when a push notification is received by the app and `opened` when a push notification is clicked.

By default, the `messaging-push-fcm` package automatically tracks `opened` and `delivered` for push notifications originating from Customer.io. Otherwise, you can track push metrics with the `trackMetric` method.

```kotlin
CustomerIO.instance().trackMetric(
    deliveryID = deliveryId,
    deviceToken = deliveryToken,
    event = MetricEvent.delivered
)
```

## Customizing Push Notifications[](#customizing-push-notifications)

You can customize the icon and color of push notifications by updating your [`AndroidManifest` as recommended by FCM](https://firebase.google.com/docs/cloud-messaging/android/client#manifest).

```xml
<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" />
```

However, if you want more control over your notifications’ appearance and behavior, Customer.io SDK provides an option to override these settings on the app side. You can customize notification appearance by implementing `CustomerIOPushNotificationCallback` and overriding the `onNotificationComposed` method.

```kotlin
class MainApplication : Application(), CustomerIOPushNotificationCallback {
    override fun onCreate() {
        super.onCreate()
        val builder = CustomerIOConfigBuilder(
            applicationContext = this,
            cdpApiKey = "your-cdp-api-key",
        ).autoTrackActivityScreens(true)
            .addCustomerIOModule(
                ModuleMessagingPushFCM(
                    moduleConfig = MessagingPushModuleConfig.Builder().apply {
                        setNotificationCallback(this)
                    }.build()
                )
            )
        CustomerIO.initialize(builder.build())
    }

    override fun onNotificationComposed(
        payload: CustomerIOParsedPushPayload,
        builder: NotificationCompat.Builder
    ) {
        // Customize your notification here
    }
}
```

You cannot override `PendingIntent` for notifications. If you want to override the behavior when people tap your notifications, you can implement `onNotificationClicked` as [described in our deep links documentation](/integrations/sdk/android/push/deep-links).

### The push notification icon[](#the-push-notification-icon)

You’ll set the icon that appears on normal push notifications as a part of your app manifest. 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.

```xml
<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" />
```