APNs2 Migration Guide
PubNub's Mobile Push Notifications gateway bridges native message publishing with third-party push notification services including Apple Push Notification service (APNs) and Firebase Cloud Messaging (FCM).
Apple's legacy binary protocol for APNs Mobile Push Notifications will be permanently shut down on March 31, 2021 (announcement here). Apple Push Notification service will no longer support the legacy binary protocol after this date, and users will need to move to the newer HTTP/2 APIs. If you use PubNub to deliver mobile push notifications to Apple devices, your users won't be impacted by this deprecation.
PubNub has already taken the necessary steps for our customers. If your application uses APNs1 certificates with PubNub, we'll continue to process your requests. However, we strongly recommend that you take steps to migrate to use our new APNs2 service. This guide documents the steps you need to follow to migrate to our new APNs2 service.
Applicable to APNs1 only
This guide is only applicable to existing customers using APNs1 certificates. If you already use APNs2 token-based mobile push notifications, no action is required.
What's new in APNs2
PubNub supports both PushKit APNs and VoIP mobile push notifications with APNs2. The services use a token signing key from your account to sign requests and call Apple's HTTP/2 APIs.
Support for APNs2 comes with the following changes:
-
New data model for tracking Apple push configuration information for keysets. To use this, you must reconfigure your keys.
-
New device registration API. To use this, you must update your client applications with the new SDK API methods.
-
Updated payload structure. To use Apple's new HTTP/2 push API, you must either update all applications that have push-related publishes, or create a PubNub Function to augment the data with the new structure.
Migration steps
Follow these steps to migrate to our new APNs2 service.
Step 1: Configure APNs2 settings on your key
On the Admin Portal, go to the Key Options page to configure APNs2 on your keys. PubNub allows keys to be configured with dual-mode. This means that both APNs1 certificate and APNs2 token can be specified on the same keys. You can also optionally create a new key instead of adding settings on existing keys. When you create a new key, it's automatically set to work with APNs2.
If your keys don't show the APNs2 settings to upload tokens, please contact PubNub Support for further assistance.
Old APNs1 settings
Your key should already be set up with a certificate for APNs1 mobile push notifications. This configuration requires no change so your apps can continue to receive APNs1 mobile push notifications as you transition to the new service.
New APNs2 settings
Follow these steps to configure APNs2 settings on your key:
-
Log in to your Apple Developer account and obtain a valid authentication token signing key (
.p8
file extension). Refer to the Apple Developer documentation for more information on how to register your app and obtain a signing key. -
On the Admin Portal, go to the Mobile Push Notifications section on the Key Options page.
-
Select the APNs2 tab and click Upload Token File to upload the authentication token signing key. The remaining fields are populated automatically.
Step 2: Add new channel registrations for devices
Next, you need to add new channel registrations for devices to use APNs2 notifications. Upgrade to the latest SDK version, and follow the code sample in this section to add environment
and topic
parameters to add a device to one or more channels. Also, set the pushGateway
to apns2
so the device is tied to the APNs2 gateway. Update the code on your server if you perform this operation from a server instead of the client applications.
SDK versions
Make sure your SDK supports APNs2. For JavaScript, you need SDK v4.27.3 or higher; for Swift, v2.3.0 or higher; and for Objective-C, v4.12.0 or higher. Earlier versions don't support APNs2. If you're using one of our other SDKs, check the SDK's changelog.
Old APNs1 methods
- JavaScript
- Swift
- Objective-C
pubnub.push.addChannels({
channels: ['ch1', 'ch2'],
device: 'deviceToken',
pushGateway: 'apns'
},
function(status) {
if (status.error) {
console.log("operation failed w/ error:", status);
} else {
console.log("operation done!")
}
}
);
pubnub.addPushChannelRegistrations(
["channelSwift"],
for: deviceToken
) { result in
switch result {
case let .success(channels):
print("The list of channels added for push: \(channels)")
case let .failure(error):
print("Failed Push Modification Response: \(error.localizedDescription)")
}
}
[self.client addPushNotificationsOnChannels:@[@"wwdc",@"google.io"]
withDevicePushToken:self.devicePushToken
pushType:PNAPNSPush
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
} else {
}
}];
New APNs2 methods
- JavaScript
- Swift
- Objective-C
pubnub.push.addChannels(
{
channels: ['ch1', 'ch2'],
device: 'deviceToken',
pushGateway: 'apns2',
environment: 'production', // required for APNs2
topic: 'com.mycompany.mybundleid' // required for APNs2
},
function(status) {
console.log(status);
}
);
pubnub.modifyAPNSDevicesOnChannels(
byRemoving: [],
thenAdding: ["ch1", "ch2"],
device: deviceToken,
on: "com.mycompany.mybundleid",
environment: .production
) { result in
switch result {
case let .success(response):
print("Successful Push Modification Response: \(response)")
case let .failure(error):
print("Failed Push List Response: \(error.localizedDescription)")
}
}
[self.client addPushNotificationsOnChannels:@[@"wwdc",@"google.io"]
withDevicePushToken:self.devicePushToken
pushType:PNAPNS2Push
environment:PNAPNSProduction
topic:@"com.my-application.bundle"
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
} else {
}
}];
Step 3: Verify the new registrations
Once device registrations are added, you should confirm the APNs2 registrations for the device by listing all channels that the device is registered with. The following code returns a list of channels for the device deviceToken
.
- JavaScript
- Swift
- Objective-C
pubnub.push.listChannels(
{
device: deviceToken,
pushGateway: 'apns2',
topic: 'com.mycompany.mybundleid',
environment: 'production'
},
function(status) {
console.log(status);
}
);
pubnub.listAPNSPushChannelRegistrations(for: deviceToken, on: "com.app.bundle", environment: .production) { result in
switch result {
case let .success(response):
print("Successful Push List Response: \(response)")
case let .failure(error):
print("Failed Push List Response: \(error.localizedDescription)")
}
}
[self.client pushNotificationEnabledChannelsForDeviceWithPushToken:self.devicePushToken
pushType:PNAPNS2Push
environment:PNAPNSDevelopment
topic:@"com.my-application.bundle"
andCompletion:^(PNAPNSEnabledChannelsResult *result, PNErrorStatus *status)
{
if (!status.isError) {
// Handle downloaded list of channels using: result.data.channels
} else {
}
}];
Step 4: Add push payload to messages
APNs2 introduces additional required fields in the message payload. PubNub can deliver both APNs1 and APNs2 notifications with the same message - just make sure to include the required APNs2 fields in the message. The APNs1 payload is delivered to APNs1 devices registered on the channel, and the APNs2 payload is delivered to APNs2 devices registered on the channel.
To update your message payload to support APNs2, make sure your payload is structured as follows. You don't need to change the underlying publish
method. The method sends the message to PubNub, along with the push payload.
The pn_apns
payload consists of:
{
"pn_apns": {
"aps": {
// necessary items
},
"pn_push": {
// necessary items
},
"pn_debug": true,
"pn_ttl": 60
}
aps
The aps
dictionary contains the keys used by Apple to deliver the notification to the user's device. The keys specify the type of interactions that you want the system to use when alerting the user. Refer to the Apple Developer documentation for more information.
pn_push
The pn_push
object contains the configuration of the push message.
Key | Type | Required | Default | Description |
---|---|---|---|---|
push_type | String | No | alert | Available values: alert , background , voip , complication , fileprovider , or mdm . Refer to apns_push_type in the Apple Developer documentation for more information. |
auth_method | String | No | token | Available values: token , cert , or certificate |
targets:environment | String | No | development | Apple environment for the certificate associated with the PubNub key-set in use. Available values: development or production . |
targets:topic | String | Yes | Bundle ID of your target application | |
targets:excluded_devices | [String] | No | A list of device tokens that should be excluded from receiving the notification. Typically, you can add your own device so you don't get a notification you publish. | |
version | String | Yes | Set to v2 . | |
pn_collapse_id | String | No | An identifier to join multiple notifications into a single notification. |
Additional Parameters
Key | Type | Required | Description |
---|---|---|---|
pn_debug | boolean | No | A flag that enables publishing push debugging info to the pndebug channel. For more information, refer to Mobile Push Troubleshooting. |
pn_ttl | int | No | Time in seconds after which the notification expires. |
Old APNs1 message payload
{
"text":"hello world",
"pn_apns":{
"aps":{
"alert":"hello world",
}
}
}
New APNs2 message payload
{
"text":"hello world",
"pn_apns":{
"aps":{
"alert":"hello world"
},
"pn_push":[
{
"push_type": "alert",
"auth_method": "token",
"targets":[
{
"environment":"production",
"topic":"bundle_id"
}
show all 21 linesPush Payload using Functions
If you're unable to modify the message payload on client apps you can also trigger serverless logic using Functions. The function will add the additional APNs2 fields in the message before it is published so you don't have to update your client app. For more information, refer to the sample Function code here.
- JavaScript
- Swift
- Objective-C
//publish on channel
pubnub.publish(
{
channel: 'ch1'
message: payload
},
function (status, response) {
console.log(status);
}
);
pubnub.publish(
channel: "ch1",
message: payload
) { result in
switch result {
case let .success(response):
print("Successful Response: \(response)")
case let .failure(error):
print("Failed Response: \(error.localizedDescription)")
}
}
self.client publish:nil toChannel:channel mobilePushPayload: payloads
withCompletion:^(PNPublishStatus *status) {
if (!status.isError) {
}
else {
}
}];
Step 5: Remove old channel registrations for devices
The last step in the process is to remove old APNs1 device registrations from the channels. This step is required to avoid receiving duplicate notifications on your devices. The sample code below shows how to remove device registrations from the apns
gateway. This operation can be performed from your server instead of the client applications.
- JavaScript
- Swift
- Objective-C
pubnub.push.removeChannels({
channels: ['ch1', 'ch2'],
device: 'deviceToken',
pushGateway: 'apns'
},
function(status) {
if (status.error) {
console.log("operation failed w/ error:", status);
} else {
console.log("operation done!")
}
}
);
pubnub.removePushChannelRegistrations(
["channelSwift"],
for: deviceToken
) { result in
switch result {
case let .success(channels):
print("The list of channels added for push: \(channels)")
case let .failure(error):
print("Failed Push Modification Response: \(error.localizedDescription)")
}
}
[self.client removePushNotificationsFromChannels:@[@"wwdc",@"google.io"]
withDevicePushToken:self.devicePushToken
pushType:PNAPNSPush
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
} else {
}
}];
Debug mobile push notifications
You can debug push notification issues by inspecting the messages published to a {channelName}-pndebug
channel. For example, if you publish a message on channel ch1
, the corresponding debug channel is ch1-pndebug
. You can subscribe to a debug channel using the PubNub Debug Console to troubleshoot push errors like invalid device tokens or invalid push payload. For more information about push troubleshooting, refer to Mobile Push Troubleshooting.