Migrate to APNs2 push notifications
If your keyset still uses a certificate-based APNs1 configuration for Mobile Push Notifications to Apple Push Notification service (APNs) devices, follow this guide to move to token-based APNs2 push. A keyset can hold an APNs1 certificate and an APNs2 token at the same time. That means you can complete every step below without a hard cutover: existing APNs1 devices keep receiving notifications until you remove their registrations in the last step.
Apple retired the legacy binary APNs protocol on March 31, 2021. PubNub still processes APNs1 certificate-based requests, so nothing breaks if you wait. But Apple no longer develops that protocol, so plan to complete this migration.
Before you start
Confirm you have:
- A paid Apple Developer Program membership, to create the APNs2 authentication key.
- Access to the Admin Portal for the keyset you're migrating.
- An SDK version that exposes APNs2 device-registration methods, such as
addAPNSDevicesOnChannelsin the Swift SDK or thepushGateway: 'apns2'option in the JavaScript SDK. Check your platform's reference in Available SDKs if you're not sure your version supports it.
Migrate with an AI coding assistant
If you use an AI coding assistant, paste this prompt into it to update your code. The prompt makes the assistant read this guide, list the affected code first, and stop before it changes push payloads or removes APNs1 registrations. Do the Apple Developer and Admin Portal steps in Configure APNs2 on your keyset yourself.
Migrate this codebase's PubNub push notifications from certificate-based APNs1
to token-based APNs2.
1. Read the migration guide first:
https://www.pubnub.com/docs/migration-guides/apns2-push-notifications.md
If the PubNub MCP server is connected, you can call get_general_migration_guide
instead. Where the guide and your own knowledge of PubNub SDKs disagree,
follow the guide and tell me.
2. Before you edit anything, list every APNs device registration and removal
call, such as pushGateway 'apns' or addPushChannelRegistrations. Also list
every publish payload that contains pn_apns, and the PubNub SDK version in use. Then show me
a plan and wait for my approval.
3. Before you change code, ask me to confirm that I uploaded the APNs2 .p8 token
file to the keyset in the Admin Portal. You can't do that step.
4. Change device registrations to APNs2. Keep the channels and device token,
show all 32 linesConfigure APNs2 on your keyset
Create an APNs2 authentication key in your Apple Developer account, then hand it to PubNub.
- Sign in to your Apple Developer account and select Certificates, Identifiers & Profiles.
- Select Keys in the sidebar, then select the add button (+) to register a new key.
- Give the key a name, select the Apple Push Notifications service (APNs) checkbox, then select Continue and Register.
- Select Download. You get a file named something like
AuthKeyABCD1234.p8. Apple lets you download it once, so keep it somewhere safe. - Note the Key ID, the part of the filename between
AuthKeyand.p8. Also note your Team ID, the 10-character string next to your team name under Membership details. - Open the Admin Portal and select the app and keyset you're migrating.
- Go to the Key Options page and scroll to the Mobile Push Notifications section.
- Select the APNs2 tab, then select Upload Token File and choose the
.p8file you downloaded. This also populates the Team ID and Auth Key ID fields from the file, so confirm they match what you noted above. - Save the keyset.
Existing certificate stays active
Uploading a token doesn't remove your existing APNs1 certificate. Both configurations stay active on the keyset until you decide to remove the certificate yourself.
If your keyset doesn't show the APNs2 tab, contact PubNub Support before continuing.
Add APNs2 device registrations
Update the device-registration calls in your client or server code. APNs2 registration takes two extra parameters that APNs1 didn't need: environment (development or production) and topic (your app's bundle identifier).
Before: APNs1
- JavaScript
- Swift
1pubnub.push.addChannels(
2 {
3 channels: ['ch1', 'ch2'],
4 device: 'deviceToken',
5 pushGateway: 'apns',
6 },
7 function (status) {
8 if (status.error) {
9 console.log('operation failed w/ error:', status);
10 }
11 }
12);
1pubnub.addPushChannelRegistrations(
2 ["ch1", "ch2"],
3 for: deviceToken
4) { result in
5 switch result {
6 case let .success(channels):
7 print("The list of channels added for push: \(channels)")
8 case let .failure(error):
9 print("Failed Push Modification Response: \(error.localizedDescription)")
10 }
11}
After: APNs2
- JavaScript
- Swift
1
The same snippet also shows the equivalent Firebase Cloud Messaging (FCM) call. Ignore that block if you're migrating Apple push only.
1
Use development while you test with an Xcode-installed build, and production for TestFlight and App Store builds. Other SDKs, including Objective-C, migrate the same way: keep the channels and device token, drop the old push type, and add the topic and environment your APNs2 method expects. Check your platform's reference in Available SDKs for the exact method signature.
Verify the new registrations
Confirm the device is registered on the channels you expect before you touch the message payload or remove anything.
- JavaScript
- Swift
1
1
An empty result means the registration in Step 2 didn't take effect. Recheck the topic and environment before moving on. You can also run this check without writing code by following Check push device registration, which calls the same lookup over REST.
Add the APNs2 fields to your push payload
APNs2 needs two fields inside pn_apns.pn_push that APNs1 didn't require: version, set to v2, and a targets entry naming the topic and environment to send to. PubNub can deliver both APNs1 and APNs2 notifications from the same publish, so you don't need to change the publish() call itself, only the payload you pass to it. For every other pn_push field, refer to Push notification format configuration.
Before: APNs1
1{
2 "text": "hello world",
3 "pn_apns": {
4 "aps": {
5 "alert": "hello world"
6 }
7 }
8}
After: APNs2
- JavaScript
- Swift
1
buildPayload() returns the pn_apns object shown below. Pass it as the message for your channel's publish() call.
1{
2 "pn_apns": {
3 "aps": {
4 "alert": {
5 "title": "Chat invitation",
6 "body": "You have been invited to 'quiz' chat"
7 }
8 },
9 "pn_push": [
10 {
11 "targets": [
12 { "topic": "com.meetings.chat.app", "environment": "development" }
13 ],
14 "version": "v2"
15 }
show all 18 lines1
| Item | Limit |
|---|---|
| Push credentials per keyset | 1 APNs certificate and 1 FCM key |
| Push notification payload size | 2 KB for APNs, 4 KB for FCM |
Can't update the client
If you can't ship a client update that changes the payload, add the APNs2 fields on the server instead with a PubNub Function that runs before the publish completes.
Remove the APNs1 registrations
Once every device you care about is verified on APNs2, remove its APNs1 registration. A device left registered under both gateways receives every push notification twice.
- JavaScript
- Swift
1pubnub.push.removeChannels(
2 {
3 channels: ['ch1', 'ch2'],
4 device: 'deviceToken',
5 pushGateway: 'apns',
6 },
7 function (status) {
8 if (status.error) {
9 console.log('operation failed w/ error:', status);
10 }
11 }
12);
1
Run Check push device registration afterward to confirm the channel list under the old push type is empty. Once it is, you can also remove the APNs1 certificate from the keyset in the Admin Portal, since nothing on that keyset uses it anymore.
Related tasks
- Mobile push notifications. How PubNub bridges publishing with APNs and FCM, and why the same event can arrive twice.
- Send push notifications on iOS. Set up a new iOS integration with APNs2 from scratch instead of migrating one.
- Check push device registration. Confirm a device token's current channel registrations with a single REST call.
- Debug push notification messages. Read the
-pndebugcompanion channel to see why a push failed after the migration. - Available SDKs. Find the mobile push API reference and minimum SDK version for your platform.