OneSignal Help & Documentation

Welcome to the OneSignal New IA developer hub. You'll find comprehensive guides and documentation to help you start working with OneSignal New IA as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    Discussions

Service Extensions

Using the iOS and Android Notification Service Extension in your mobile apps.

Quick Reference

Details

iOS Notification Service Extension

Follow the SDK Setup Guide used in your app to get started if not done so already.

Troubleshooting iOS Notification Service Extension

If you run into issues with the iOS NSE not working, like not getting images or badges not handled correctly.

Android Notification Service Extension

Setup the optional NotificationServiceExtension class in your app to receive data in the background with or without displaying a notification.
Override specific notification settings depending on client-side app logic such as custom accent color, vibration pattern, or other any other NotificationCompat options available.

See Android's documentation on the NotificationCompat options.

Android Notification Service Extension

Add the below Notification Extension Code if you want to do one of the following:

  • Receive data in the background with or without displaying a notification.
  • Override specific notification settings depending on client side app logic such as custom accent color, vibration pattern, or other any other NotificationCompat options available. See Android's documentation on the NotificationCompat options.

🚧

Requires writing Native Android code & Upgraded SDK

Must be using OneSignal SDK Versions:

  • Android 4.0.0+
  • React Native 4.0.0+
  • Flutter 3.0.0+
  • Cordova/Ionic 3.0.0+

See Mobile SDKs API Migration Guides to upgrade the OneSignal SDK.

For Unity, Xamarin, Huawei or if you did not update to the latest SDK versions listed above, follow this Service Extension Guide.

Step 1. Create a class for the Service Extension

Create a class that extends OSRemoteNotificationReceivedHandler and implement the remoteNotificationReceived method.

The method remoteNotificationReceived parameters are context of type Context and notificationReceivedEvent of type OSNotificationReceivedEvent.

package your.package.name
  
import android.content.Context;
import android.util.Log;
import org.json.JSONObject;

import com.onesignal.OSNotification;
import com.onesignal.OSMutableNotification;
import com.onesignal.OSNotificationReceivedEvent;
import com.onesignal.OneSignal.OSRemoteNotificationReceivedHandler;

@SuppressWarnings("unused")
public class NotificationServiceExtension implements OSRemoteNotificationReceivedHandler {

    @Override
    public void remoteNotificationReceived(Context context, OSNotificationReceivedEvent notificationReceivedEvent) {
        OSNotification notification = notificationReceivedEvent.getNotification();

        // Example of modifying the notification's accent color
        OSMutableNotification mutableNotification = notification.mutableCopy();
        mutableNotification.setExtender(builder -> {
            // Sets the accent color to Green on Android 5+ devices.
            // Accent color controls icon and action buttons on Android 5+. Accent color does not change app title on Android 10+
            builder.setColor(new BigInteger("FF00FF00", 16).intValue());
            // Sets the notification Title to Red
            Spannable spannableTitle = new SpannableString(notification.getTitle());
            spannableTitle.setSpan(new ForegroundColorSpan(Color.RED),0,notification.getTitle().length(),0);
            builder.setContentTitle(spannableTitle);
            // Sets the notification Body to Blue
            Spannable spannableBody = new SpannableString(notification.getBody());
            spannableBody.setSpan(new ForegroundColorSpan(Color.BLUE),0,notification.getBody().length(),0);
            builder.setContentText(spannableBody);
            //Force remove push from Notification Center after 30 seconds
            builder.setTimeoutAfter(30000);
            return builder;
        });
        JSONObject data = notification.getAdditionalData();
        Log.i("OneSignalExample", "Received Notification Data: " + data);

        // If complete isn't call within a time period of 25 seconds, OneSignal internal logic will show the original notification
        // To omit displaying a notification, pass `null` to complete()
        notificationReceivedEvent.complete(mutableNotification);
    }
}

Step 2. Add the following to your AndroidManifest.xml.

Add OneSignal class name and your class value as meta-data within the AndroidManifest.xml file under the application tag. Ignore any "unused" warnings.

<application ...> 
  <!-- name doesn't change, value = your class fully name spaced-->
  <meta-data android:name="com.onesignal.NotificationServiceExtension"
     android:value="com.onesignal.example.NotificationServiceExtension" />
</application>

Getting a payload from a notification

Major Release SDKs (4.x.x) see the OSNotification class

Additionally, the payload object has the following two parameters:

Name

Type

Details

restoring

boolean

True if the notification was restored after an app update, device reboot, and app opened after being force killed. If you have customized any alerting / priority settings check the restoring flag before applying them. You may want to omit displaying if your notification is no longer relevant to the user.

isAppInFocus

boolean

True if the app is open and in focus when the notification arrives.


iOS Notification Service Extension

Setup instructions can be found in each individual SDK setup guide.

Apple's docs on the UNNotificationServiceExtension.

The following features requires the Notification Service Extension:

Getting a payload from an iOS notification

In this example, we are setting Additional Data through the OneSignal dashboard to {"custom_message":"Hullabaloo, Caneck, Caneck"}

NSDictionary* dict = request.content.userInfo;
NSString* custom = [dict objectForKey:@"custom"];
NSString* aps = [dict objectForKey:@"aps"];

NSLog(@"Running NotificationServiceExtension: custom = %@", custom);
NSLog(@"Running NotificationServiceExtension: aps = %@", aps);
let userInfo = request.content.userInfo

print("Running NotificationServiceExtension: userInfo = \(userInfo.description)")

Example console output:
The additional data can then be extracted from the custom object using the a parameter...


Troubleshooting the iOS Notification Service Extension

If you are having issues with Confirmed Deliveries or Images not showing on iOS mobile apps follow this guide.

1 Open the NotificationService.m or NotificationService.swift and replace the whole file contents with the below code. (The code is the same as our original setup code, just adding some additional logging.

#import <OneSignal/OneSignal.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];
    
    [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
    
    // DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting
    //            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];
    
  NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.onesignal.jonexample.onesignal"];
    NSLog(@"NSE player_id: %@", [userDefault  stringForKey:@"GT_PLAYER_ID"]);
    NSLog(@"NSE app_id: %@", [userDefault  stringForKey:@"GT_APP_ID"]);
    
    self.contentHandler(self.bestAttemptContent);
}

- (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.
    
    [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
    
    self.contentHandler(self.bestAttemptContent);
}

@end
import UserNotifications
import OneSignal
import os.log

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
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        let userInfo = request.content.userInfo
        let custom = userInfo["custom"]
        print("Running NotificationServiceExtension: userInfo = \(userInfo.description)")
        print("Running NotificationServiceExtension: custom = \(custom.debugDescription)")
      //debug log types need to be enabled in Console > Action > Include Debug Messages
        os_log("%{public}@", log: OSLog(subsystem: "com.your.bundleid", category: "OneSignalNotificationServiceExtension"), type: OSLogType.debug, userInfo.debugDescription)
        

        
        if let bestAttemptContent = bestAttemptContent {
            OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }
    
    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 {
            OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }
    
}

2 Set your Active Scheme to the OneSignalNotificationServiceExtension.

3 Build and run the project in Xcode on your device. Then select Window > Devices and Simulators

4 Select Open Console

5 In the Console

  • Select Action > Include Debug Messages
  • Search for OneSignalNotificationServiceExtension as the CATEGORY
  • Send this device a notification with a message (contents)

You should see a message logged with the app running and not running.

Updated about a month ago


Service Extensions


Using the iOS and Android Notification Service Extension in your mobile apps.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.