Ionic/Cordova/Capacitor SDK

Instructions for adding the OneSignal SDK to your Ionic or Capacitor app for iOS, Android, Amazon Fire apps

Requirements

  • Ionic v2 or newer
  • Cordova 9.1.0 or newer
  • Capacitor 2.0.0 or newer
  • Cordova [email protected] or newer
  • CocoaPods version 1.12.1+ Install with the following from the Terminal:
  • Cordova [email protected] or newer
  • iOS: iOS 11+ or iPadOS 11+ device (iPhone, iPad, iPod Touch) to test on. Xcode 14+ simulator works running iOS 16+
  • iOS: mac with Xcode 12+
  • Android: Android 5.0+ device or emulator with "Google Play Store (Services)" installed
  • Configured OneSignal App and Platform

Configure your OneSignal App and Platform

Details on configuring your OneSignal App and Platform (click to expand)

If you haven't already, sign up for a free account on onesignal.com.

You can setup multiple platforms (iOS, Android, Web, Email, SMS) within the same OneSignal App under Settings > Platforms. If you want to create a new app select New App/Website. If this is your first OneSignal app, you will see the next page.



Name your app and organization something recognizable, then select the platform to setup. You can always set up more platforms in this OneSignal App later within Settings > Platforms.

Click Next: Configure Your Platform.


To configure your app, follow the prompts based on the platforms you support.

After you setup your credentials, click Save & Continue.

Choose your Apps Target SDK, the click Save & Continue.


Finally, you will be directed to install the SDK and provided your OneSignal App ID. Make sure to save your App ID as you will need it later.

If you need a teammate or your developer to assist, you can click Invite them to the app and select Done when finished.


Continue through the documentation to finish adding OneSignal to your app.

Setup

1. Add SDK

Run the following from your project directory.

npm install onesignal-cordova-plugin
npx cap sync
cordova plugin add onesignal-cordova-plugin

2. iOS Setup

Open the .xcworkspace file in Xcode located your project's ios folder.

Select the root project > your main app target > Signing & Capabilities.

If you do not see Push Notifications enabled, click + Capability and add Push Notifications.

Click + Capability again and add Background Modes. Then check Remote notifications.

Add Notification Service Extension

The OneSignalNotificationServiceExtension allows your iOS application to receive rich notifications with images, buttons, and badges. It's also required for OneSignal's Confirmed Delivery analytics features.

In Xcode Select File > New > Target...

Select Notification Service Extension then Next.

Enter the product name as OneSignalNotificationServiceExtension and press Finish.

Do not activate the scheme on the dialog that is shown after selecting "Finish".

Press Cancel on the "Activate" scheme prompt.

By canceling, you keep debugging your app instead of the extension you just created. If you activated by accident, you can switch back to debug your app target near the middle-top next to the device selector.

By cancelling, you keep Xcode debugging your app instead of the extension you just created. If you activated it by accident, you can switch back to debug your app target (middle-top next to the device selector).

Select the OneSignalNotificationServiceExtension target and General settings.

Set Minimum Deployments to be the same value as your Main Application Target. This should be iOS 11 or higher.

Set the OneSignalNotificationServiceExtension Target Minimum Deployments value to be the same as your Main Application Target.

Set the OneSignalNotificationServiceExtension Target Minimum Deployments value to be the same as your Main Application Target

Add App Groups

App Groups allow your app and the OneSignalNotificationServiceExtension to communicate when a notification is received, even if your app is not active. This is required for badges and Confirmed Deliveries.

Select your Main App Target > Signing & Capabilities > + Capability > App Groups.

Within App Groups, click the + button.

Set the App Groups container to be group.YOUR_BUNDLE_IDENTIFIER.onesignal where YOUR_BUNDLE_IDENTIFIER is the same as your Main Application "Bundle Identifier".

Press OK and repeat for the OneSignalNotificationServiceExtension Target.

Select the OneSignalNotificationServiceExtension Target > Signing & Capabilities > + Capability > App Groups.

Within App Groups, click the + button.

Set the App Groups container to be group.YOUR_BUNDLE_IDENTIFIER.onesignal where YOUR_BUNDLE_IDENTIFIER is the same as your Main Application "Bundle Identifier".

DO NOT INCLUDE OneSignalNotificationServiceExtension.

Do not include OneSignalNotificationServiceExtension

Do not include OneSignalNotificationServiceExtension

Optional instructions to setup custom App Group Name (click to expand)

This step is only required if you do not want to use the default app group name (which is group.{your_bundle_id}.onesignal).

Open your Info.plist file and add a new OneSignal_app_groups_key as a String type.

Enter the group name you checked in the last step as it's value.

Make sure to do the same for the Info.plist under the OneSignalNotificationServiceExtension folder.

Add OneSignal SDK to the OneSignalNotificationServiceExtension

In the ios directory of your project, open the Podfile and add the following outside of the main target (should be at the same level as your main target):

target 'OneSignalNotificationServiceExtension' do
  pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
end
def assertDeploymentTarget(installer)
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      # ensure IPHONEOS_DEPLOYMENT_TARGET is at least 13.0
      deployment_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'].to_f
      should_upgrade = deployment_target < 13.0 && deployment_target != 0.0
      if should_upgrade
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
      end
    end
  end
end

platform :ios, '13.0'
use_frameworks!

# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true

def capacitor_pods
  pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
  pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
  pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
  pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
  pod 'CordovaPluginsStatic', :path => '../capacitor-cordova-ios-plugins'
end

target 'App' do
  capacitor_pods
  # Add your Pods here
end

post_install do |installer|
  assertDeploymentTarget(installer)
end

target 'OneSignalNotificationServiceExtension' do
  pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
end

From your terminal, navigate to this ios folder and run pod install --repo-update

In the Xcode project navigator, select the OneSignalNotificationServiceExtension folder and open the NotificationService.m or NotificationService.swift file.

Replace the whole file's contents with the following code.

import UserNotifications

import OneSignalExtension

class NotificationService: UNNotificationServiceExtension {
    
    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?
    
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent = bestAttemptContent {
            /* DEBUGGING: Uncomment the 2 lines below to check this extension is executing
                          Note, this extension only runs when mutable-content is set
                          Setting an attachment or action buttons automatically adds this */
            // print("Running NotificationServiceExtension")
            // bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
            
            OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }  
}
#import <OneSignalExtension/OneSignalExtension.h>

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.receivedRequest = request;
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    /* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is executing
                  Note, this extension only runs when mutable-content is set
                  Setting an attachment or action buttons automatically adds this */
    // NSLog(@"Running NotificationServiceExtension");
    // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
    
    [OneSignalExtension didReceiveNotificationExtensionRequest:self.receivedRequest
                       withMutableNotificationContent:self.bestAttemptContent
                                   withContentHandler:self.contentHandler];
}

- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    
    [OneSignalExtension serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
    
    self.contentHandler(self.bestAttemptContent);
}

@end
Example of the NotificationService.swift file.

Example of the NotificationService.swift file.

3. Android Setup

Verify that your target SDK version is at least version 33.

Requirements:

  • Ionic Capacitor v2 or higher
android {
    compileSdkVersion 33
    ...

    defaultConfig {
        ...
        targetSdkVersion 33
    }
}
1103

Set the Compile Sdk Version to 33.

1103

In Default Config, set the Target SDK Version to 33.

Add Android Icons (Android Only)

By default, notifications will be shown with a small bell icon in the notification shade. Follow the Customize Notification Icons guide to create your own small and large notification icons for your app.

4. Initialization

When creating a new Ionic + Capacitor/Cordova project inside of the Ionic Dashboard or using the CLI, you get the option to choose what kind of project you want to create.

Instructions for Cordova (click to expand)

Instructions for Cordova

Add the following to your javascript file in www/js


document.addEventListener('deviceready', OneSignalInit, false);
function OneSignalInit() {
    // Remove this method to stop OneSignal Debugging
    window.plugins.OneSignal.Debug.setLogLevel(6);

    // Uncomment to set OneSignal visual logging to VERBOSE
    // window.plugins.OneSignal.Debug.setAlertLevel(6);

    // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
    window.plugins.OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");

  	//Adds an event listener for clicks on notifications
  	const listener = (event: NotificationClickEvent) => {
        const notificationPayload = JSON.stringify(event);
        console.log(notificationPayload);
    };
    window.plugins.OneSignal.Notifications.addEventListener("click", listener);
  
    //Prompts the user for notification permissions.
    //    * Since this shows a generic native prompt, we recommend instead using an In-App Message to prompt for notification permission (See step 6) to better communicate to your users what notifications they will get.
     window.plugins.OneSignal.Notifications.requestPermission(true).then((accepted) => {
        console.log("User accepted notifications: " + accepted);
    });
}
Instructions for Ionic + Capacitor (Angular) (click to expand)

Add the following to your src/app/app.component.ts.

import OneSignal from 'onesignal-cordova-plugin';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {
  constructor() {
    // Remove this method to stop OneSignal Debugging
    OneSignal.Debug.setLogLevel(6)
    
    // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
    OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");

    OneSignal.Notifications.addEventListener('click', async (e) => {
      let clickData = await e.notification;
      console.log("Notification Clicked : " + clickData);
    })

    OneSignal.Notifications.requestPermission(true).then((success: Boolean) => {
      console.log("Notification permission granted " + success);
    })
  }
}

import OneSignal from 'onesignal-cordova-plugin';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {
  constructor() {
    // Remove this method to stop OneSignal Debugging
    OneSignal.Debug.setLogLevel(6)
    
    // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
    OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");

    OneSignal.Notifications.addEventListener('click', async (e) => {
      let clickData = await e.notification;
      console.log("Notification Clicked : " + clickData);
    })

    OneSignal.Notifications.requestPermission(true).then((success) => {
      console.log("Notification permission granted " + success);
    })
  }
}

Instructions for Ionic + Capacitor (React) (click to expand)

Add the following to your src/App.tsx or src/index.tsx.

import OneSignal from 'onesignal-cordova-plugin';

const App: React.FC = () => {
  // Remove this method to stop OneSignal Debugging
  OneSignal.Debug.setLogLevel(6)
  
  // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
  OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");

  OneSignal.Notifications.addEventListener('click', async (e) => {
    let clickData = await e.notification;
    console.log("Notification Clicked : " + clickData);
  })

  OneSignal.Notifications.requestPermission(true).then((success: Boolean) => {
    console.log("Notification permission granted " + success);
  })
};
import OneSignal from 'onesignal-cordova-plugin';

const App = ()  => {
  // Remove this method to stop OneSignal Debugging
  OneSignal.Debug.setLogLevel(6)
  
  // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
  OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");

  OneSignal.Notifications.addEventListener('click', async (e) => {
    let clickData = await e.notification;
    console.log("Notification Clicked : " + clickData);
  })

  OneSignal.Notifications.requestPermission(true).then((success) => {
    console.log("Notification permission granted " + success);
  })
};
Instructions for Ionic + Capacitor (Vue) (click to expand)

Add the following to your src/main.ts.

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import  OneSignal   from 'onesignal-cordova-plugin';
import { IonicVue } from '@ionic/vue';


const app = createApp(App)
  .use(IonicVue)
  .use(router);

router.isReady().then(() => {
  app.mount('#app');
    OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");
    OneSignal.Notifications.requestPermission();
});
Instructions for Ionic + Cordova (Angular) (click to expand)

Add the following to your src/app/app.component.ts.

constructor(platform: Platform) {
    platform.ready().then(() => {
      // Remove this method to stop OneSignal Debugging
      OneSignal.Debug.setLogLevel(6);
  
      // Uncomment to set OneSignal visual logging to VERBOSE  
      // OneSignal.Debug.setAlertLevel(6);

      // Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID
      OneSignal.initialize("YOUR_ONESIGNAL_APP_ID");
  
  
      let myClickListener = async function(event) {
        let notificationData = JSON.stringify(event);
      };
      OneSignal.Notifications.addEventListener("click", myClickListener);
  

      // Prompts the user for notification permissions.
      // Since this shows a generic native prompt, we recommend instead using an In-App Message to prompt for notification permission (See step 7) to better communicate to your users what notifications they will get.
      OneSignal.Notifications.requestPermission(true).then((accepted: boolean) => {
        console.log("User accepted notifications: " + accepted);
      });
    });
  }

Note: If you are using Capacitor, you may need to update the Capacitor Configuration iOS property handleApplicationNotifications to false to allow OneSignal to handle iOS push notifications.

const config: CapacitorConfig = {
  // ... additional configuration
  
  ios: {
    // ... additional configuration
    handleApplicationNotifications: false
  }
};

iOS Automatic Builds (Optional)

If you are using an automated build system, you may run into issues where the Push Notification capability is not enabled for your project. In order to resolve this problem, you can follow these steps:

In your Xcode project, make sure the Push Notifications capability (as well as any other capabilities your app needs).

Close the Xcode project. In the /platforms/ios folder you will see a {yourProjectName}.entitlements file. Copy this file to the root of your Cordova project.

Edit your config.xml file to include the following. Make sure to replace [yourProjectName] with the name of your project.

<platform name="ios">
    <resource-file src="[yourProjectName].entitlements" />
</platform>

5. Testing

Run your app on a physical device to make sure it builds correctly.

If you used the provided code, then the requestPermission method, should prompt you to subscribe to push notifications. You can change this later.

Check your OneSignal Dashboard Audience > Subscriptions to see your User & Subscription Record.

Then head over to Messages > New Push to Send your first Push Notification from OneSignal.

πŸ“˜

Troubleshooting

If you run into any issues please see our Cordova Variants troubleshooting guide.

Try the example project on our Github repository.

If stuck, contact support directly or email [email protected] for help.

For faster assistance, please provide:

  • Your OneSignal App Id
  • Details, logs, and/or screenshots of the issue.
  • Steps to reproduce

Recommended

Push permission with In-App Message

You can continue to opt-in users to push via the requestPermission method. However, Apple's Human Interface Guidelines recommends that apps "Create an alert, modal view, or other interface that describes the types of information they want to send and gives people a clear way to opt in or out."

OneSignal provides In-App Messages to meet this recommendation and have a better user experience. This also permits you to ask for permission again in the future, since the native permission prompt is limited to how many times it can show and cannot be shown again if the user clicks deny.

See How to Prompt for Push Permissions with In-App Messages for details on implementing this.

Identify Users

Required if using integrations.
Recommended for messaging across multiple channels (push, email, sms).

OneSignal creates subscription-level records under a unique ID called the subscription_id. A single user can have multiple subscription_id records based on how many devices, email addresses, and phone numbers they use to interact with your app.

If your app has its own login system to track users, call login at any time to link all channels to a single user. For more details, see Aliases & External ID.

let externalId = '123456789'; // You will supply the external user id to the OneSignal SDK
OneSignal.login("externalId");
let externalId = '123456789'; // You will supply the external user id to the OneSignal SDK
window.plugins.OneSignal.login("externalId");

Set Email and Phone Number

Recommended if using Email and SMS messaging.

Use the provided SDK methods to capture email and phone number when provided. Follow the channel quickstart guides for setup:

// Ionic 5 Capacitor may need to use (window as any).plugins.OneSignal
OneSignal.User.addEmail("[email protected]");

// Ionic 5 Capacitor may need to use (window as any).plugins.OneSignal
OneSignal.User.addSms("+11234567890");
window.plugins.OneSignal.User.addEmail("[email protected]");

window.plugins.OneSignal.User.addSms("+11234567890");

Add Data Tags

Optional

Tags are custom key : value pairs of String data used for tracking user events and properties. Setting tags is required for more complex segmentation and message personalization.

See Data Tags for more details.

OneSignal.User.addTags({key: "value", key2: "value2"});
window.plugins.OneSignal.User.addTags({key: "value", key2: "value2"});