PubNub Logo Docs
Support Contact Sales Login Try Our APIs

›First steps

Collapse all
Dark mode

Home

  • Home

First steps

  • Set up your account
  • Get the SDK
  • Initialize PubNub
  • Identify users and devices
  • Send messages
  • Receive messages
  • Retrieve old messages
  • Check user presence
  • Add custom metadata
  • Manage access
  • Add serverless business logic
  • Send push notifications

Setup

  • PubNub account
  • Application
  • Users & devices
  • Connection management
  • Data security
  • Data persistence
  • API limits

Chat

  • In-App Chat

SDKs

  • SDKs

Messages

  • Publish
  • Receive
  • Actions
  • Payload type conventions

Channels

  • Basics
  • Subscription
  • Naming conventions

User presence

  • Basics
  • Events
  • State
  • Webhooks

Metadata

  • Channel
  • User
  • Membership

Message Persistence

  • Message Persistence

File sharing

  • File sharing

Access management

  • Manage access

Push notifications

  • Basics
  • iOS
  • Android
  • Troubleshooting

Best practices

  • Architectural choices
  • Message aggregation
  • Friend list & status feed
  • Troubleshooting
  • Migration guides

Serverless processing

    EVENTS & ACTIONS

    • Basics
    • Configure Events & Actions

    FUNCTIONS

    • Basics
    • Development guidelines
    • Functions API
    • Custom integrations

Debug Console
Network Status

Send push notifications

One of the features that PubNub offers is the ability to connect to Android and iOS push notification services.

This is done by creating a key from one, or both, of those providers and adding it to your PubNub Admin Portal.

It's possible to use Google/Firebase in iOS applications, so the choice is yours whether you want to manage both services.

PubNub Portal Push Key location

Request a push notification token for the device

For every device that you'd like to receive a push notification on, you must register with the notification provider. Refer to the Android, iOS, and Firebase for iOS documentation on how to get this set up.

Register and cache your token

Now that you're set up with your token, you'll need to make sure as tokens are created by your service, that your app is always using the correct token. This means collecting, replacing, and caching. For caching you can use UserDefaults for iOS and SharedPreferences for Android.

To create the cache:

Swift
Objective-C
Java
Kotlin
let tokenDispatch = DispatchQueue(label: "com.pubnub.deviceToken", attributes: .concurrent)
var cachedToken: Data? {
get {
var token: Data?
tokenDispatch.sync {
token = UserDefaults.standard.data(forKey: "com.pubnub.deviceToken")
}
return token
}
set {
tokenDispatch.async(flags: .barrier) {
UserDefaults.standard.set(newValue, forKey: "com.pubnub.deviceToken")
}
}
}
static dispatch_queue_t deviceTokenDispatch;
static dispatch_queue_t pushChannelsDispatch;

static dispatch_once_t registerCustomDispatchOnceToken;
- (void) registerCustomDispatchQueues {
dispatch_once(&registerCustomDispatchOnceToken, ^{
deviceTokenDispatch = dispatch_queue_create("com.pubnub.deviceToken", DISPATCH_QUEUE_CONCURRENT);
pushChannelsDispatch = dispatch_queue_create("com.pubnub.pushChannels", DISPATCH_QUEUE_CONCURRENT);
});
}

- (nullable NSData *) cachedToken {
__block NSData* token;
dispatch_sync(tokenDispatch, ^{
token = [[NSUserDefaults standardUserDefaults] dataForKey: @"com.pubnub.deviceToken"];
});
return token;
}
- (void) setCachedToken:(nullable NSData *) newValue {
dispatch_barrier_async(tokenDispatch, ^{
[[NSUserDefaults standardUserDefaults] setValue:newValue forKey:@"com.pubnub.deviceToken"];
});
}

Go to SDK

public class SharedPreferencesManager {
private static SharedPreferences sharedPref;
private SharedPreferencesManager() { }

public static void init(Context context) {
if(sharedPref == null)
sharedPref = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
}

public static final String FCM_DEVICE_TOKEN = "PUBNUB_FCM_DEVICE_TOKEN";
public static @Nullable String readDeviceToken() {
return sharedPref.getString(FCM_DEVICE_TOKEN, null)
}
public static void writeDeviceToken(String value) {
SharedPreferences.Editor prefsEditor = sharedPref.edit();
prefsEditor.putString(FCM_DEVICE_TOKEN, value);
prefsEditor.apply();
}

public static final String FCM_CHANNEL_LIST = "PUBNUB_FCM_CHANNEL_LIST";
public static @Nullable String[] readChannelList() {
return (String[]) sharedPref.getStringSet(FCM_CHANNEL_LIST, null).toArray();
}
public static void writeChannelList(Set<String> value) {
SharedPreferences.Editor prefsEditor = sharedPref.edit();
prefsEditor.putStringSet(FCM_CHANNEL_LIST, value);
prefsEditor.apply();
}
}

Go to SDK

class SharedPreferencesManager private constructor()  {
companion object {
private val sharePref = SharedPreferencesManager()
private lateinit var sharedPreferences: SharedPreferences

private val PLACE_OBJ = "place_obj"
private val FCM_DEVICE_TOKEN = "PUBNUB_FCM_DEVICE_TOKEN"
private val FCM_CHANNEL_LIST = "PUBNUB_FCM_CHANNEL_LIST"


fun getInstance(context: Context): SharedPreferencesManager {
if (!::sharedPreferences.isInitialized) {
synchronized(SharedPreferencesManager::class.java) {
if (!::sharedPreferences.isInitialized) {
sharedPreferences = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
}
}
}
return sharePref
}
}

fun readDeviceToken(): String? = sharedPreferences.getString(FCM_DEVICE_TOKEN, null)
fun writeDeviceToken(value: String?) = sharedPreferences.edit().putString(FCM_DEVICE_TOKEN, value).apply()

fun readChannelList(): List<String> = sharedPreferences.getStringSet(FCM_CHANNEL_LIST, null)?.toList().orEmpty()
fun writeChannelList(value: Set<String>?) = sharedPreferences.edit().putStringSet(FCM_CHANNEL_LIST, value).apply()
}

Now, let's catch and replace the tokens as they come in.

Swift
Objective-C
Java
Kotlin

Apple Docs

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let oldDeviceToken = self.cachedToken
guard deviceToken != oldDeviceToken else { return }
self.cachedToken = deviceToken

updateAPNSDevicesOnChannels(
pushChannels.allObjects, newDevice: deviceToken, oldDevice: oldDeviceToken,
on: "com.mycompany.mybundleid", environment: .production
) { result in
switch result {
case .success: print("Successfully updated channels with new token")
case let .failure(error): print("Failed to update device token due to: \(error)")
}
}
}

Apple Docs

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSData *oldDevice = self.cachedToken;
if ([deviceToken isEqualToData:oldDevice]) { return; }
self.cachedToken = deviceToken;

[self updateAPNSDevicesOnChannels:[self.pushChannels allObjects]
withDevicePushToken:deviceToken
replacingDevicePushToken:oldDevice
pushType:PNAPNS2Push
environment:PNAPNSProduction
topic:@"com.mycompany.mybundleid"
andCompletion:^(PNAcknowledgmentStatus * _Nonnull status) {
if (!status.isError) {
NSLog(@"Successfully updated channels with new token");
} else {
NSLog(@"Failed to update device token due to: %@", status);
}
}];
}

Go to SDK

public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override public void onNewToken(String token) {
String oldToken = SharedPreferencesManager.readDeviceToken();
if (token.equals(oldToken)) { return; }
SharedPreferencesManager.write(token);

updatePushNotificationsOnChannels(SharedPreferencesManager.readChannelList(), token, oldToken);
}
}

Go to SDK

override fun onNewToken(token: String) {
val oldToken = SharedPreferencesManager.getInstance(applicationContext).readDeviceToken()
if (token == oldToken) { return }
SharedPreferencesManager.getInstance(applicationContext).writeDeviceToken(token)

updatePushNotificationsOnChannels(
SharedPreferencesManager.getInstance(applicationContext).readChannelList(),
token,
oldToken
)
}

Connect the device to a channel

For your app to know that what you're sending is going to be a push notification, you'll need to define certain channels to be push channels. In the code examples below you'll see Ch1 and Ch2 as the two channels being added.

Swift
Objective-C
Java
Kotlin

Go to SDK

if let deviceToken = (UIApplication.shared.delegate as? AppDelegate)?.cachedToken {
pubnub.addAPNSDevicesOnChannels(
["ch1", "ch2"],
device: deviceToken,
on: "com.mycompany.mybundleid",
environment: .production
) { result in
switch result {
case let .success(channelsAdded):
channelsAdded.forEach { (UIApplication.shared.delegate as? AppDelegate)?.pushChannels.update(with: $0) }
case let .failure(error): print("Failed to add Push due to: \(error.localizedDescription)")
}
}
}

Go to SDK

NSData *deviceToken = [(AppDelegate *)[[UIApplication sharedApplication] delegate] cachedToken];
if (deviceToken == nil) { return; }

[self.client addPushNotificationsOnChannels:@[@"ch1",@"ch2"]
withDevicePushToken:deviceToken
pushType:PNAPNS2Push
environment:PNAPNSProduction
topic:@"com.mycompany.mybundleid"
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
NSSet* cachedChannels = [(AppDelegate *)[[UIApplication sharedApplication] delegate] pushChannels];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setPushChannels:[cachedChannels setByAddingObjectsFromArray:@[@"ch1",@"ch2"]]];
} else { NSLog(@"Failed to add Push due to: %@", status); }
}];

Go to SDK

String cachedToken = SharedPreferencesManager.readDeviceToken();

pubnub.addPushNotificationsOnChannels()
.pushType(PNPushType.FCM)
.deviceId(cachedToken)
.channels(Arrays.asList("ch1", "ch2", "ch3"))
.async(new PNCallback<PNPushAddChannelResult>() {
@Override
public void onResponse(PNPushAddChannelResult result, PNStatus status) {
// Handle Response
}
});

Go to SDK

SharedPreferencesManager.getInstance(applicationContext).readDeviceToken()?.also { deviceToken ->
pubnub.addPushNotificationsOnChannels(
pushType = PNPushType.FCM,
deviceId = deviceToken,
channels = listOf("ch1", "ch2", "ch3")
).async { result, status ->
// Handle Response
}
}

Building the push notification message

When constructing the Push message you wish to send you need to specify whether you're using Apple Push Notification pn_apns or Firebase (Google) Cloud Message pn_gcm in your payload. APN will require you to define the environment (development or production) and the Bundle ID of your app using topic.

For Apple Push Notification Service:

JSON
Swift
Objective-C
{
"text": "John invited you to chat",
"pn_apns": {
"aps": {
"alert": {
"title": "Chat Invitation",
"body": "John invited you to chat"
}
},
"pn_push":[
{
"push_type": "alert",
"auth_method": "token",
"targets":[
{
"environment":"production",
"topic":"com.mycompany.mybundleid",
"excluded_devices": ["device-token1", "device-token2"]
}
],
"version":"v2"
}
]
}
}

Go to SDK

let message = ["text": "John invited you to chat"]

let pushPayload = PubNubPushMessage(
apns: PubNubAPNSPayload(
aps: APSPayload(alert: .object(.init(title: "Chat Invitation", body: "John invited you to chat"))),
pubnub: [.init(targets: [.init(topic: "com.mycompany.mybundleid", environment: .production)])],
),
additional: message
)

Go to SDK

NSDictionary *message = @{
@"text": @"John invited you to chat"
};

PNNotificationsPayload *pushData = [PNNotificationsPayload
payloadsWithNotificationTitle:@"Chat Invitation"
body:@"John invited you to chat"];

// create the APNs target with topic and environment
PNAPNSNotificationTarget *target = [PNAPNSNotificationTarget
targetForTopic:@"com.mycompany.mybundleid"
inEnvironment:PNAPNSProduction
withExcludedDevices:nil];

// create the APNs config object and add the target
PNAPNSNotificationConfiguration *apnsConfig =
[PNAPNSNotificationConfiguration configurationWithTargets:@[target]];

// add the APNs config to the main pushData object
pushData.apns.configurations = @[apnsConfig];

// generate the final pushPayload object
NSDictionary *pushPayload = [pushData dictionaryRepresentationFor:PNAPNS2Push|PNFCMPush];

For Firebase (Including Firebase for iOS):

JSON(Apple)
Swift
Objective-C
JSON (Firebase)
Java
Kotlin
{
"text": "John invited you to chat",
"pn_gcm": {
"topic": "invitations",
"apns": {
"payload": {
"aps": {
"alert": {
"title": "Chat Invitation",
"body": "John invited you to chat"
}
}
},
"headers": {
"apns-push-type": "alert",
"apns-topic": "com.mycompany.mybundleid",
"apns-priority": "10"
}
},
"pn_exceptions" : ["device-token1", "device-token2"]
}
}

Go to SDK

let message = ["text": "John invited you to chat"]

let pushPayload = PubNubPushMessage(
fcm: PubNubFCMPayload(
payload: nil,
target: .topic("invitations"),
apns: FCMApnsConfig(
headers: [
"apns-push-type": "alert", "apns-topic": "com.mycompany.mybundleid", "apns-priority": "10"
],
payload: APSPayload(alert: .object(.init(title: "Chat Invitation", body: "John invited you to chat")))
)
),
additional: message
)

Go to SDK

NSDictionary *message = @{
@"text": @"John invited you to chat"
};

NSDictionary *pushPayload = @{
@"text": @"John invited you to chat",
@"pn_gcm": @{
@"to": @"invitations",
@"apns": @{
@"payload": @{
@"aps": @{
@"alert": @{
@"title": @"Chat Invitation",
@"body": @"John invited you to chat"
}
},
},
@"headers": @{
@"apns-push-type": @"alert",
@"apns-topic": @"com.mycompany.mybundleid",
@"apns-priority": @"10"
}
},
@"pn_exceptions": @[@"device-token1", @"device-token2"]
}
};
{
"text": "John invited you to chat",
"pn_gcm": {
"topic": "invitations",
"android": {
"notification": {
"title": "Chat Invitation",
"body": "John invited you to chat"
}
},
"pn_exceptions" : ["device-token1", "device-token2"]
}
}

Go to SDK

PushPayloadHelper pushPayloadHelper = new PushPayloadHelper();
PushPayloadHelper.FCMPayload fcmPayload = new PushPayloadHelper.FCMPayload();
PushPayloadHelper.FCMPayload.Notification fcmNotification =
new PushPayloadHelper.FCMPayload.Notification()
.setTitle("Chat Invitation")
.setBody("John invited you to chat");

fcmPayload.setNotification(fcmNotification);
pushPayloadHelper.setFcmPayload(fcmPayload);

Map<String, Object> commonPayload = new HashMap<>();
commonPayload.put("text", "John invited you to chat");
pushPayloadHelper.setCommonPayload(commonPayload);

Map<String, Object> pushPayload = pushPayloadHelper.build();

Go to SDK

val pushPayloadHelper = PushPayloadHelper()

val fcmPayload = FCMPayload().apply {
notification = FCMPayload.Notification().apply {
title = "Chat Invitation"
body = "John invited you to chat"
}
custom = mapOf(
"topic" to "invitations",
"pn_exceptions" to arrayOf("device-token1", "device-token2")
)
}
pushPayloadHelper.fcmPayload = fcmPayload

pushPayloadHelper.commonPayload = mapOf(
"John invited you to chat" to "text"
)

val pushPayload = pushPayloadHelper.build()

Send the Push Notification

Just like when sending any other message with PubNub, we use the publish method to push notifications. For push notifications to work we must send a message on the channels that we registered for push notifications in the previous steps.

Java
Kotlin
Javascript
Swift
Objective-C

Go to SDK

pubnub.publish()
.channel("ch1")
.message(pushPayload)
.async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
// Handle Response
}
});

Go to SDK

pubnub.publish(
channel = "ch1",
message = pushPayload
).async { result, status ->
// Handle Response
}

Go to SDK

//publish on channel
pubnub.publish(
{
channel: "ch1"
message: pushPayload
},
function (status, response) {
// Handle Response
}
);

Go to SDK

pubnub.publish(channel: "ch1", message: pushPayload) { result in
switch result {
case let .success(timetoken):
print("Successfully published message at: \(timetoken)")
case let .failure(error):
print("Failed to publish due to: \(error)")
}
}

Go to SDK

[self.pubnub publish:message toChannel:@"ch1" mobilePushPayload:pushPayload
withCompletion:^(PNPublishStatus *status) {
if (!status.isError) {
NSLog(@"Successfully published message");
} else {
NSLog(@"Failed to publish due to: %@", status);
}
}];
← Add serverless business logicPubNub account →
  • Request a push notification token for the device
  • Register and cache your token
  • Connect the device to a channel
  • Building the push notification message
  • Send the Push Notification
© PubNub Inc. - Privacy Policy