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

# Push Notifications

> Set up and customize push notifications with the Userpilot Capacitor Plugin

Userpilot SDK supports handling push notifications to help you deliver targeted messages and enhance user engagement.

### **Android Setup:**

**Prerequisites**

It is recommended to configure your Android push settings in the [Userpilot Settings Studio](https://run.userpilot.io/settings/mobile) before setting up push notifications in your app.

To obtain the required keys and configuration details, please refer to the [Android Push Notification Guide](./android-push-notification-setup-guide).

**Setting up**

This guide assumes this is the first time code is being added to your project related to setting up push notifications using Google services (Firebase Cloud Messaging). In the case your project is already configured for push, proceed to Step 2.

**Step 1. Add Firebase**

Follow the steps in the official Google documentation on [How to add Firebase to your project](https://firebase.google.com/docs/android/setup).

**Step 2. Request Notifications Permission**

Starting from **Android 13 (API level 33)**, apps \*\*must explicitly request the \*\*`POST_NOTIFICATIONS` **permission** in order to display push notifications.

The Userpilot Capacitor plugin **automatically** requests push notifications permission on its own.

**Step 3. Add the Userpilot Firebase Messaging Service**

Firebase connects to your app through a `<service>` . Go to your Manifest file under `example-app -> android -> app -> manifest` and add:

```xml theme={null}
 <service
 android:name="com.userpilot.pushNotifications.UserpilotFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

If your project has already added a child of FirebaseMessagingService, you can leave it as is, and instead plug in `UserpilotFirebaseMessagingService` to your service class.

```kotlin theme={null}
import com.userpilot.pushNotifications.UserpilotFirebaseMessagingService
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class CustomFirebaseMessageService : FirebaseMessagingService() {
    override fun onMessageReceived(message: RemoteMessage) {
        if (UserpilotFirebaseMessagingService.handleMessage(baseContext, message)) {
           // handled as Userpilot message
           return
        }

        // not Userpilot message
        super.onMessageReceived(message)
        }

    override fun onNewToken(token: String) {
       // sets new token from the callback
       UserpilotFirebaseMessagingService.setToken(token)

       super.onNewToken(token)
    }
}
```

**Step 4. Deep Linking**

To ensure your app **opens automatically when a Userpilot push notification is clicked**, you need to configure an `intent-filter` in your app's \*\*entry \*\*`Activity` under `example -> android -> app -> manifest` .

This configuration enables deep linking based on a custom scheme defined in your app.

**Define the Deep Link Scheme** In your `userpilot.xml` configuration file, you should have defined a value for `userpilot_push_notification` , check Step 5.

**Update Manifest** file to include the intent-filter as below. Make sure to set `host="sdk"` .

```xml theme={null}
<activity
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation"
    android:name=".MainActivity"
    android:label="@string/title_activity_main"
    android:theme="@style/AppTheme.NoActionBarLaunch"
    android:launchMode="singleTask"
    android:exported="true">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
            <data android:scheme="userpilot_push_notification" android:host="sdk"/>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
        </intent-filter>
    </activity>
```

**Step 5. Customizing**

The Userpilot SDK allows for some customizations that will change how your messages will be delivered to your end users. These properties are set as `<resources>` properties. In order change those properties create a file under `res/values` under `example-app -> android -> app` and set it to desired values.

```xml theme={null}
<resources>
    <!-- Small icon displayed in the notification bar -->
    <drawable name="userpilot_notification_small_icon">@drawable/ic_notification</drawable>

    <!-- Accent color applied to notification UI elements -->
    <color name="userpilot_notification_color">#6765E8</color>

    <!-- Determines if notifications are visible on the lock screen (true = visible) -->
    <bool name="userpilot_notification_channel_lock_screen_visibility">true</bool>

    <!-- Enables notification lights for the channel -->
    <bool name="userpilot_notification_channel_enable_light">true</bool>

    <!-- Enables vibration for the notifications -->
    <bool name="userpilot_notification_channel_enable_vibration">true</bool>

    <!-- Unique ID for the notification channel -->
    <string name="userpilot_notification_channel_id">com.userpilot.general.channel</string>

    <!-- Human-readable name for the notification channel -->
    <string name="userpilot_notification_channel_name">General</string>

    <!-- Description shown to the user about this notification channel -->
    <string name="userpilot_notification_channel_description">Default channel used for app messages</string>

    <!-- Importance level of the notification channel (0 = NONE, 5 = MAX) -->
    <integer name="userpilot_notification_channel_importance">3</integer>

    <!-- Key used to identify Userpilot push notifications OR user default scheme using userpilot-USERPILOT_TOKEN -->
    <string name="userpilot_custom_scheme">userpilot_custom_scheme</string>
</resources>
```

### **iOS Setup**

**Prerequisites**

It is recommended to configure your iOS push settings in the [Userpilot Settings Studio](https://run.userpilot.io/settings/mobile) before setting up push notifications in your app.

To obtain the required keys and configuration details, please refer to the [iOS Push Notification Guide](./ios-push-notification-setup-guide).

**Enabling Push Notification Capabilities**

In Xcode, navigate to the Signing & Capabilities section of your main app target and add the Push Notifications capability.

**Configuring Push Notifications**

The Userpilot iOS SDK supports receiving push notification so you can reach your users whenever the moment is right.

There are two options for configuring push notification: automatic or manual.

Automatic configuration is the quickest and simplest way to configure push notifications and is recommended for most customers.

**Automatic App Configuration**

Automatic configuration takes advantage of swizzling to automatically provide the necessary implementations of the required `UIApplicationDelegate` and `UNUserNotificationCenterDelegate` methods.

To enable automatic configuration, call `Userpilot.enableAutomaticPushConfig()` from `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)` inside` example-app -> ios -> AppDelegate.swift` .

```swift theme={null}
func application(
_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
   // Automatically configure for push notifications
   Userpilot.enableAutomaticPushConfig()

   // Override point for customization after application launch.
}
```

Automatic configuration seamlessly integrates with your app's existing push notification handling. It processes only Userpilot notifications, while ensuring that all other notifications continue to be handled by your app’s original logic.

**Manually Configuring Push Notifications**

Step 1. Enable push capabilities\
Step 2. Register for push notifications\
Step 3. Set push token for Userpilot\
Step 4. Enable push response handling\
Step 5. Configure foreground handling

Full source code:

```swift theme={null}
// AppDelegate+PushNotification.swift

import Foundation
import UserNotifications
import UserpilotCapacitor

extension AppDelegate: UNUserNotificationCenterDelegate {
    /// Call from `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`
    func setupPush(application: UIApplication) {
        requestPushNotificationPermission()
        
        // 1: Register to get a device token
        application.registerForRemoteNotifications()

        UNUserNotificationCenter.current().delegate = self
    }

    // MARK: - Push Notification Permission Request, In case you didn't request it from your Capacitor app.
    private func requestPushNotificationPermission() {
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]

        // Check if the app has already been authorized
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            if settings.authorizationStatus == .authorized {
                // App is already authorized for push notifications
                // Register for remote notifications again to get the device token
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            } else {
                // If not authorized, request permission
                UNUserNotificationCenter.current().requestAuthorization(options: options) { (granted, error) in
                    if granted {
                        DispatchQueue.main.async {
                            UIApplication.shared.registerForRemoteNotifications()
                        }
                    } else {
                        if let errorDescription = error?.localizedDescription {
                            print("Permission denied or failed to request: \(errorDescription)")
                        } else {
                            print("Permission denied or failed to request: Unknown error")
                        }
                    }
                }
            }
        }
    }

    // 2: Pass device token to Userpilot
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        UserpilotPlugin.setPushToken(deviceToken)
    }

    // 3: Pass the user's response to a delivered notification to Userpilot
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        if UserpilotPlugin.didReceiveNotification(response: response, completionHandler: completionHandler) {
            return
        }

        completionHandler()
    }

    // 4: Configure handling for notifications that arrive while the app is in the foreground
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        if #available(iOS 14.0, *) {
            completionHandler([.banner, .list])
        } else {
            completionHandler(.alert)
        }
    }
}
```

<Frame>
  [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com)
</Frame>
