> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.qonversion.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Handling Qonversion Notifications

<Warning>
  **Deprecated.** The `Qonversion.Automations.shared()` / `QONAutomations sharedInstance` /
  `Automations.getSharedInstance()` / `Automations.shared` references in the snippets below come
  from the legacy `Automations` SDK module, which has been removed from current iOS and Android
  SDKs. The replacement `NoCodes` module currently does not expose `setNotificationsToken`,
  `handleNotification`, or `getNotificationCustomPayload`. The code on this page will not compile
  against the latest SDK; treat as historical until the push API surface is reintroduced.
</Warning>

## iOS Push Notifications

### 1. Set notifications token

Override [`application(_:didRegisterForRemoteNotificationsWithDeviceToken:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622958-application) to handle notifications token.\
Call the `setNotificationsToken()` method to enable Qonversion to send the push notifications.

```swift theme={null}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Qonversion.Automations.shared().setNotificationsToken(deviceToken)
}
```

```objectivec theme={null}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [[QONAutomations sharedInstance] setNotificationsToken:deviceToken];
}
```

### 2. Handle notifications

Override the [`userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter) method to handle received notifications. Call `handleNotification()` with the notification data. The method returns true when a push notification is received from Qonversion, and Qonversion SDK will try to handle it. If you have not set up the in-app screen with Qonversion, you need to handle a notification yourself.\
For push notifications from other services, the method returns false, so you also need to handle a notification yourself.

```swift theme={null}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let isPushHandled: Bool = Qonversion.Automations.shared().handleNotification(response.notification.request.content.userInfo)
    if !isPushHandled {
      // Handle notification yourself
    }
    completionHandler()
}
```

```objectivec theme={null}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center 
didReceiveNotificationResponse:(UNNotificationResponse *)response 
         withCompletionHandler:(void (^)(void))completionHandler {
    BOOL isPushHandled = [[QONAutomations sharedInstance] handleNotification:response.notification.request.content.userInfo];
    if (!isPushHandled) {
      // Handle notification yourself
    }
    completionHandler();
}
```

## Android Push Notifications

### 1. Set notifications token

To enable Qonversion push notifications, call `setNotificationsToken()` and pass a device registration token. <a href="https://firebase.google.com/docs/cloud-messaging/android/client#sample-register" target="_blank" rel="noopener">Here</a> you can find more information about the ways to retrieve the token.\
You have to call the `setNotificationsToken` method for every newly generated token.

```java theme={null}
Automations.getSharedInstance().setNotificationsToken(token);
```

```kotlin theme={null}
Automations.shared.setNotificationsToken(token)
```

### 2. Handle notifications

To define what happens when users click on push notifications, you have to specify an instance of the `PendingIntent` object and pass the `RemoteMessage` as extra data. Then call the `setContentIntent()` method of the `NotificationCompat.Builder`.

```java theme={null}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

    String title = remoteMessage.getData().get("title");
    String body = remoteMessage.getData().get("body");

    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(this, NotificationActivity.class);
    // If you need, set the intent flag for activity
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    // Save the RemoteMessage object as extra data
    intent.putExtra(INTENT_REMOTE_MESSAGE, remoteMessage);
    // Flag FLAG_ONE_SHOT indicates that this PendingIntent can be used only once
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(title)
            .setContentText(body)
      		.setSmallIcon(R.drawable.ic_notification)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent);
  
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    // For notificationId use any unique value you want to be an ID for the notification. 
    notificationManager.notify(notificationId, notificationBuilder.build());
}
```

```kotlin theme={null}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
    super.onMessageReceived(remoteMessage)
    
    val title = remoteMessage.data["title"]
    val body = remoteMessage.data["body"]

    // Create an explicit intent for an Activity in your app
    val intent = Intent(this, NotificationActivity::class.java)
    // If you need, set the intent flag for the activity
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    // Save the RemoteMessage object as extra data
    intent.putExtra(INTENT_REMOTE_MESSAGE, remoteMessage)
    // Flag FLAG_ONE_SHOT indicates that this PendingIntent can be used only once
    val pendingIntent: PendingIntent =
        PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)

    val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle(title)
        .setContentText(body)
        .setSmallIcon(R.drawable.ic_notification)
        // Set the intent that will fire when the user taps the notification
        .setContentIntent(pendingIntent)

    with(NotificationManagerCompat.from(this)) {
        // For notificationId use any unique value you want to be an ID for the notification
        notify(notificationId, notificationBuilder.build())
    }
}
```

> 🚧 [Applications that target Android 12](https://developer.android.com/about/versions/12/behavior-changes-12#foreground-service-launch-restrictions) or higher can't start activities from services or broadcast receivers that are used as notification trampolines. Make sure you use Activity as an automation push handler for notification intent.

In the NotificationActivity `onCreate()` method, retrieve an instance of the `RemoteMessage` and call `handleNotification()` with the message data. The method returns true when a push notification is received from Qonversion and Qonversion SDK will try to handle it. If you have not set up the in-app screen with Qonversion, you need to handle a notification yourself.\
For push notifications from other services, the method returns false, so you also need to handle a notification yourself.

```java theme={null}
RemoteMessage remoteMessage = getIntent().getParcelableExtra(INTENT_REMOTE_MESSAGE);
if (remoteMessage != null && !Automations.getSharedInstance().handleNotification(remoteMessage.getData)) {
 	// Handle notification yourself
}
```

```kotlin theme={null}
val remoteMessage: RemoteMessage? = intent.getParcelableExtra(INTENT_REMOTE_MESSAGE)
if (remoteMessage != null && !Automations.shared.handleNotification(remoteMessage.data)) {
   // Handle notification yourself
}
```

## Cross-platform Push Notifications

### 1. Set notifications token

Call the `setNotificationsToken()` method to enable Qonversion push notifications. Pass APNs token for iOS devices or Firebase Cloud Messaging token for Android devices.\*\*\*\*

```javascript Flutter theme={null}
Automations.getSharedInstance().setNotificationsToken(notificationsToken);
```

```javascript React Native theme={null}
Automations.getSharedInstance().setNotificationsToken(notificationsToken);
```

```csharp Unity theme={null}
Automations.GetSharedInstance().SetNotificationsToken(notificationsToken);
```

### 2. Handle notifications

Call `handleNotification()` with the notification data to define what happens when users click on push notifications. The method returns true when a push notification is received from Qonversion and Qonversion SDK will try to handle it. If you have not set up the in-app screen with Qonversion, you need to handle a notification yourself.\
For push notifications from other services, the method returns false, so you also need to handle a notification yourself.

> 📘 Notification data
>
> The `handleNotification` method accepts an object instance of Map. Retrieving this object depends on your implementation of push notifications.

```javascript Flutter theme={null}
final isNotificationHandled = await Automations.getSharedInstance().handleNotification(notificationData);
if (!isNotificationHandled) {
  // Handle notification yourself
}
```

```javascript React Native theme={null}
const isNotificationHandled = await Automations.getSharedInstance().handleNotification(notificationData);
if (!isNotificationHandled) {
  // Handle notification yourself
}
```

```csharp Unity theme={null}
bool isNotificationHandled = Automations.GetSharedInstance().HandleNotification(notificationData);
if (!isNotificationHandled)
{
  // Handle notification yourself
}
```

## Custom payload

You can add a custom payload to the notification while creating it in the Qonversion dashboard. The data should be a valid JSON object. Neither JSON arrays nor simple values like strings or integers are allowed. It is done to simplify the method's return value type. Then you can get parsed payload on your client side using the following method of the corresponding SDK providing the received push notification data.

```swift theme={null}
let customPayload: [AnyHashable:Any]? = Qonversion.getNotificationCustomPayload(response.notification.request.content.userInfo)
```

```objectivec theme={null}
NSDictionary *customPayload = [Qonversion getNotificationCustomPayload:response.notification.request.content.userInfo];
```

```java theme={null}
final Map<String, Object> customPayload = Automations.getSharedInstance().getNotificationCustomPayload(remoteMessage.getData());
```

```kotlin theme={null}
val customPayload: Map<String, Any?>? = Automations.shared.getNotificationCustomPayload(remoteMessage.data)
```

```javascript Flutter theme={null}
final customPayload = await Automations.getSharedInstance().getNotificationCustomPayload(notificationData);
```

```javascript React Native theme={null}
const customPayload = await Automations.getSharedInstance().getNotificationCustomPayload(notificationData);
```

```csharp Unity theme={null}
Dictionary<string, object> customPayload = Automations.GetSharedInstance().GetNotificationCustomPayload(notificationData);
```

The method return value is nullable for the cases when there is no custom payload in the notification, or any error occurs while parsing.
