Push Notifications
PubNub's in-app messaging is a low-latency, bidirectional solution that allows you to deliver secure, access-restricted, and encrypted message payloads to any mobile device.
Migrate to APNs2
Apple is retiring version 1 of its APNs service on March 31, 2021. Please follow the steps in PubNub's APNs2 migration guide to avoid any interruption of service.
Despite the advantages of in-app messaging, there are cases where you may want to use Push Notifications. The Mobile Push Gateway provides a method to receive messages quickly and reliably via PubNub regardless of whether the application is in the foreground or background on iOS and Android.
PubNub's Mobile Push Notifications feature bridges native PubNub publishing with third-party push notification services including Firebase Cloud Messaging (FCM) and Apple Push Notification Service (APNs). The push gateway is a great way to make sure that you can send important data and messages out to users even when they are not active in your mobile application.
To use this feature, enable Mobile Push Notifications setting in the Admin Portal.
How it Works
When the Mobile Push Gateway is enabled, you may associate unique mobile devices tokens to PubNub channel names. Once this association is made, when a message is published to a channel, all associated devices will receive that message via their associated FCM or APNs service. Behind the scenes, the PubNub Mobile Push Gateway establishes an authenticated connection to the push providers based on your registered configuration.
Push notifications are delivered in the following manner:
- First, you publish a message on a channel with the push payload
- PubNub's Push Gateway checks device registrations and relays the message to push providers
- FCM/APNs providers deliver the push notification to one or more devices
Configuration
To use push notification on PubNub, you first need to enable the feature and setup FCM/APNs credentials for your application. Once you've obtained the credentials from your Apple or Firebase account, you can add those credentials or upload a certificate to the Admin Portal.
FCM
Before you can use PubNub Mobile Push Gateway with FCM, you must first setup your FCM configuration. Once you've obtained the API Key, you need to set it up in the PubNub Admin Portal.
- Create a Firebase Project on the Firebase console and click Add Firebase to your Android app and follow the steps there
- Go to Project settings by clicking the gear icon at the top left, next to Project overview
- Click the Cloud messaging tab and find the Server key.
- Add FCM API Key in the PubNub Admin Portal.
APNs
PubNub supports both PushKit APNs and VoIP push notifications. Apple Push Notification services require that a Push Token Key be generated that uniquely identifies your application to the PubNub Push Gateway. This Push Token Key should be uploaded to the PubNub Admin Portal and is used to form a secure connection with the APN service.
- Login to your Apple Developer account to obtain a valid authentication token signing key for your app. Refer to the Apple Developer Documentation for instructions.
- Enter the Team ID and Auth Key ID in the Admin Portal.
- Upload the Authentication Token Signing Key (
.p8
file extension) to the Admin Portal.
Legacy APNs1 Certificates
All new PubNub keys are automatically set to use APNs2. If you already use APNs1 certificates with PubNub, we require that you create a new keyset to use APNs2. Documentation for Legacy APNs1 Push Certificates can be found here.
If you need to enable APNs2 on an existing keyset, refer to the APNs2 Migration Guide.
Device Registrations
To use APNs or FCM, you must first register your device in the respective push notification service provider.
iOS Devices
Refer to Apple Device Registration guide for step-by-step instructions for how to register your app and retrieve your app's device token. To make it easier for you, take a look at the sample implementation below.
Include the below code at the top of AppDelegate.m
@import UserNotifications;
@import PubNub
The code below shows a sample implementation of the iOS app delegate methods needed to register for remote notifications, receive the corresponding token and add the device token to a PubNub channel.
var pubnub: PubNub!
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
/*
STEP 1: Ask user for permission to receive push; register with APNs if allowed
*/
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in
switch settings.authorizationStatus {
case .notDetermined:
center.requestAuthorization(options: [.alert, .sound, .badge],
completionHandler: { (granted, error) in
// You might want to remove this
/// or handle errors differently in production
assert(error == nil)
if granted {
UIApplication.shared.registerForRemoteNotifications()
}
})
case .authorized, .provisional:
UIApplication.shared.registerForRemoteNotifications()
case .denied:
print("We can't use notifications because the user has denied permissions")
@unknown default:
print("Unknown status")
}
}
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
/*
STEP 2: Receive device push token from APNs
*/
print("Received device push token from APNs: \(deviceToken)")
/*
STEP 3: Is the new device token different than the old device token
*/
let defaults = UserDefaults.standard
let oldDeviceToken = defaults.data(forKey: "DeviceToken")
// if token is different from previous token,
// then store locally and associate for push on channels with new token
if (oldDeviceToken != deviceToken) {
defaults.set(deviceToken, forKey: "DeviceToken")
defaults.synchronize()
if (oldDeviceToken != nil) {
pubnub.removeAllPushChannelRegistrations(for: oldDeviceToken!) { result in
switch result {
case let .success(response):
print("Successful Push Deletion Response: \(response)")
case let .failure(error):
print("Failed Push Deletion Response: \(error.localizedDescription)")
}
}
}
/*
STEP 4: associate push notifications with channels for PubNub
*/
pubnub.modifyAPNSDevicesOnChannels(
byRemoving: [],
thenAdding: ["chats.room1", "chats.room2", "alerts.system"],
device: deviceToken,
on: "com.example.chat",
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)")
}
}
}
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
// The token isn't currently available
print("Remote notification support is unavailable due to error:\(error)")
}
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler:
@escaping (UIBackgroundFetchResult) -> Void
) {
/*
STEP 5: provide a means to receive push notifications
*/
guard let aps = userInfo["aps"] as? [String: AnyObject] else {
completionHandler(.failed)
return
}
// you might just do nothing if you do not want to display anything
// there techniques for displaying silent push Notifications
// but leaving that to Apple docs for those details
}
Android Devices
Refer to Firebase Device Token guides for information on how to obtain device registration tokens for your Android devices. For a sample app that includes the code below, refer to the Firebase Quickstarts for Android GitHub repo.
The following code shows how to request a device registration token from FCM by calling FirebaseInstanceId.getInstance().getInstanceId()
. You can do this anywhere in your app but you normally want to do it in the onCreate
method of your MainActivity
.
public class MainActivity extends AppCompatActivity {
// you may lots of other code here
// you'll need to reference this in your custom class below
public static SharedPreferences sharedPrefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
// this creates the SharedPreferences you'll need in your custom class below
sharedPrefs = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);
/*
STEP 1: request a device push token from FCM
*/
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
// Log and toast (just for testing purposes)
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
// you probably have lots more code here
}
To receive the token (and updates to the token value) and push notifications, you must create a custom class that extends FirebaseMessagingService
and overrides two methods: onNewToken
and onMessageReceived
.
The onNewToken
callback fires whenever a new token is generated. In the onNewToken
method, you must replace sendRegistrationToServer
with PubNub calls to associate the device token on PubNub channels.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
// you may lots of other code here
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
@Override
public void onNewToken(String token) {
/*
STEP 2: receive the new push token
*/
String oldToken = MainActivity.preferences.getString("DeviceToken","");
Log.d(TAG, "Refreshed token: " + token);
Log.d(TAG, "Previous token: " + oldToken);
/*
STEP 3: is the new push token different than the old push token?
*/
if (!token.isEqual(oldToken)) {
// token has changed to store
MainActivity.sharedPrefs.edit().putString("DeviceToken", token).commit();
// unregister the oldToken from push channels on PubNub
pubnub.removeAllPushNotificationsFromDeviceWithPushToken()
.deviceId(oldToken).pushType(PNPushType.FCM)
.async(new PNCallback<PNPushRemoveAllChannelsResult>() {
@Override
public void onResponse(PNPushRemoveAllChannelsResult result, PNStatus status) {
}
});
/*
STEP 4: Associate push notifications on channels with PubNub
*/
pubnub.addPushNotificationsOnChannels()
.pushType(PNPushType.FCM)
.channels(Arrays.asList("chats.room1", "chats.room1", "alerts.system"))
.deviceId(deviceToken)
.async(new PNCallback<PNPushAddChannelResult>() {
@Override
public void onResponse(PNPushAddChannelResult result, PNStatus status) {
// handle response
}
});
}
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
/*
STEP 5: receive push notifications from FCM
*/
/*
There are two types of messages data messages and notification messages.
Data messages are handled here in onMessageReceived whether the app is in
the foreground or background. Data messages are the type traditionally
used with FCM. Notification messages are only received here in
onMessageReceived when the app is in the foreground. When the app is in
the background an automatically generated notification is displayed.
When the user taps on the notification they're returned to the app. Messages
containing both notification and data payloads are treated as notification
messages. The Firebase console always sends notification messages.
For more refer to: https://firebase.google.com/docs/cloud-messaging/concept-options
*/
}
// you probably have lots more code here
}
Cross-Platform Support
There are several options to choose for cross-platform mobile development, of which React Native and PhoneGap are popular choices.
React Native: For specific information on how to receive push notifications for React Native mobile applications, please refer to the React Native Push Notifications
npm
docs. There you'll see steps for Android push setup and a link to the iOS PushNotificationsIOS GitHub repo. Or you can check out the PubNub Blog: How to Setup React Native Push Notifications (iOS & Android).PhoneGap: For details on how to retrieve your mobile device push tokens and configuring for mobile gateway receipt on PhoneGap please refer to the phonegap-plugin-push github repo.
Add Device Tokens to Channels
PubNub SDKs natively support adding device registrations to channels. Once your devices are registered, published messages on the channels that include a push payload with trigger push notifications towards those devices.
The device tokens can be added to PubNub channels from client applications directly or from a back-end service using our server-side SDKs.
//fcm
pubnub.push.addChannels(
{
channels: ["chats.room1", "chats.room2", "alerts.system"],
device: deviceToken,
pushGateway: "gcm",
},
function(status) {
console.log(status);
}
);
//apns2
pubnub.push.addChannels(
{
channels: ["chats.room1", "chats.room2", "alerts.system"],
device: deviceToken,
pushGateway: "apns2",
environment: "production", // required for apns2
topic: "com.mycompany.mybundleid" // required for apns2
},
function(status) {
console.log(status);
}
);
//apns2
pubnub.modifyAPNSDevicesOnChannels(
byRemoving: [],
thenAdding: ["chats.room1", "chats.room2", "alerts.system"],
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)")
}
}
//fcm
[self.client addPushNotificationsOnChannels:@[@"chats.room1",@"chats.room2",@"alerts.system"]
withDevicePushToken:self.devicePushToken
pushType:PNFCMPush
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
// Push notifications successful enabled on passed channels.
} else {
/**
* Handle modification error. Check 'category' property to find out possible issue because
* of which request did fail. Request can be resent using: [status retry];
*/
}
}];
//apns2
[self.client addPushNotificationsOnChannels:@[@"chats.room1",@"chats.room2",@"alerts.system"]
withDevicePushToken:self.devicePushToken
pushType:PNAPNS2Push
environment:PNAPNSProduction
topic:@"com.mycompany.mybundleid"
andCompletion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
// Push notifications successful enabled on passed channels.
} else {
/**
* Handle modification error. Check 'category' property to find out possible issue because
* of which request did fail. Request can be resent using: [status retry];
*/
}
}];
//fcm
pubnub.addPushNotificationsOnChannels()
.pushType(PNPushType.FCM)
.channels(Arrays.asList("chats.room1", "chats.room1", "alerts.system"))
.deviceId(deviceToken)
.async(new PNCallback<PNPushAddChannelResult>() {
@Override
public void onResponse(PNPushAddChannelResult result, PNStatus status) {
// handle response
}
});
//apns2
pubnub.addPushNotificationsOnChannels()
.pushType(PNPushType.APNS2)
.channels(Arrays.asList("chats.room1", "chats.room1", "alerts.system"))
.deviceId("deviceToken")
.topic("com.mycompany.mybundleid")
.environment("production")
.async(new PNCallback<PNPushAddChannelResult>() {
@Override
public void onResponse(PNPushAddChannelResult result, PNStatus status) {
// handle response
}
});
//fcm
pubnub.AddPushNotificationsOnChannels()
.PushType(PNPushType.FCM)
.Channels(new string[] { "chats.room1", "chats.room2", "alerts.system" })
.DeviceId(deviceToken)
.Execute(new PNCallback<PNPushAddChannelResult>((r, s) => {
// this does not return actionable data, be sure to check the status
// on the outcome of the operation by checking the status.isError().
}));
//fcm
envelope = pubnub.add_channels_to_push()\
.push_type(PNPushType.GCM)\
.channels(["chats.room1", "chats.room2", "alerts.system"])\
.device_id(deviceToken)\
.sync()
# does not return actionable data, be sure to check the status in envelope
# on the outcome of the operation by checking the status.is_error()
//apns2
envelope = pubnub.add_channels_to_push()\
.push_type(PNPushType.APNS2)\
.channels(["chats.room1", "chats.room2", "alerts.system"])\
.device_id("deviceToken")\
.topic("com.mycompany.mybundleid")\
.environment("PNPushEnvironment.PRODUCTION")\
.sync()
# does not return actionable data, be sure to check the status in envelope
# on the outcome of the operation by checking the status.is_error()
Once device token is added, you can use the listChannels
method to confirm the channel registrations for the device.
//fcm
pubnub.push.listChannels(
{
device: deviceToken,
pushGateway: "gcm"
},
function(status) {
console.log(status);
}
);
//apns2
pubnub.push.listChannels(
{
device: deviceToken,
pushGateway: "apns2",
topic: "com.mycompany.mybundleid",
environment: "production"
},
function(status) {
console.log(status);
}
);
//apns2
pubnub. listAPNSPushChannelRegistrations(
for: deviceToken,
on: "com.mycompany.mybundleid",
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.pubnub pushNotificationEnabledChannelsForDeviceWithPushToken:self.deviceToken
pushType:PNFCMPush
andCompletion:^(PNAPNSEnabledChannelsResult *result, PNErrorStatus *status) {
NSLog(@"%@ status '%@', result '%@'", status, result);
}
];
//apns2
[self.pubnub pushNotificationEnabledChannelsForDeviceWithPushToken:self.deviceToken
pushType:PNAPNS2Push
environment:PNAPNSProduction
topic:@"com.mycompany.mybundleid"
andCompletion:^(PNAPNSEnabledChannelsResult *result, PNErrorStatus *status) {
NSLog(@"%@ status '%@', result '%@'", status, result);
}
];
//fcm
pubnub.auditPushChannelProvisions()
.deviceId(deviceToken)
.pushType(PNPushType.FCM)
.async(new PNCallback<PNPushListProvisionsResult>() {
@Override
public void onResponse(PNPushListProvisionsResult result, PNStatus status) {
// handle response
}
});
//apns2
pubnub.auditPushChannelProvisions()
.deviceId(deviceToken)
.pushType(PNPushType.APNS2)
.topic("com.mycompany.mybundleid")
.environment("production")
.async(new PNCallback<PNPushListProvisionsResult>() {
@Override
public void onResponse(PNPushListProvisionsResult result, PNStatus status) {
// handle response
}
});
//fcm
pubnub.AuditPushChannelProvisions()
.DeviceId(deviceToken)
.PushType(PNPushType.FCM)
.Execute(new PNCallback<PNPushListProvisionsResult>((r, s) => {
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(r));
}));
// returns a PNPushListProvisionsResult which contains the following property:
// Channels List<string> - List of channels registered for push notifications
/fcm
from pubnub.enums import PNPushType
envelope = pubnub.list_push_channels()\
.push_type(PNPushType.GCM)\
.device_id("deviceId")\
.sync()
# returns a PNPushListProvisionsResult which contains the following fields:
# Channels List - List of channels subscribed for push notifications.
/apns2
from pubnub.enums import PNPushType
envelope = pubnub.list_push_channels()\
.push_type(PNPushType.APNS2)\
.device_id("deviceId")\
.topic("com.mycompany.mybundleid")\
.environment("PNPushEnvironment.PRODUCTION")\
.sync()
# returns a PNPushListProvisionsResult which contains the following fields:
# Channels List - List of channels subscribed for push notifications.
Sending Push Notifications
To send a push notification, include the appropriate push notification payload for APNs, FCM or both when you publish a message and PubNub will appropriately parse the message. When PubNub finds the pn_apns
and pn_gcm
payloads, it will retrieve all device tokens that are associated for push on the target channel and forward a push notification request to the appropriate push service for those associated devices.
In the code sample below, the message includes a pn_apns
payload to trigger APNs notifications to iOS devices and a pn_gcm
payload to send an FCM notification to Android devices.
// create the realtime message data
let payload = {};
payload.text = "John invited you to chat";
payload.room = "chats.room1";
// create the generic title/message content
let pushData = PubNub.notificationPayload(
"Chat invite", "John invited you to chat");
// provide optional sound property
// and other push properties that apply to both push services
pushData.sound = "default";
// add APNS2 specific properties
pushData.apns.configurations =
[{
"targets":[{
"topic": "com.example.chat",
"environment": "production"
}]
}];
// build the the push payload for APNS2 and FCM
let pushPayload = pushData.buildPayload(["apns2", "gcm"]);
// append pushPayload to the realtime message payload
Object.assign(payload, pushPayload);
console.log(JSON.stringify(payload, null, 2));
//publish on channel
pubnub.publish(
{
channel: "inbox.user123"
message: payload
},
function (status, response) {
console.log(status);
console.log(response);
}
);
let message = ["text": "John invited you to chat", "room": "chats.room1"]
let payload = PubNubPushMessage(
apns: PubNubAPNSPayload(
aps: APSPayload(alert: .object(.init(title: "Chat invite")), sound: .string("default")),
pubnub: [.init(targets: [.init(topic: "com.example.chat", environment: .production)])],
payload: ""
),
fcm: PubNubFCMPayload(
payload: "",
target: .topic(""),
notification: FCMNotificationPayload(title: "Chat invite", body: "John invited you to chat"),
android: FCMAndroidPayload(notification: FCMAndroidNotification(sound: "default"))
),
additional: message
)
print(payload)
//publish on channel
pubnub.publish(
channel: "inbox.user123",
message: payload
) { result in
switch result {
case let .success(response):
print("Successful Response: \(response)")
case let .failure(error):
print("Failed Response: \(error.localizedDescription)")
}
}
NSDictionary *payload = @{
@"text": @"John invited you to chat",
@"room": @"chats.room1"
};
PNNotificationsPayload *pushData = [PNNotificationsPayload
payloadsWithNotificationTitle:@"Chat invite"
body:@"John invited you to chat"];
// create the APNS2 target with topic and environment
PNAPNSNotificationTarget *target = [PNAPNSNotificationTarget
targetForTopic:@"com.example.chat"
inEnvironment:PNAPNSProduction
withExcludedDevices:nil];
// create the APNS2 config object and add the target
PNAPNSNotificationConfiguration *apnsConfig =
[PNAPNSNotificationConfiguration configurationWithTargets:@[target]];
// add the APNS2 config to the main pushData object
pushData.apns.configurations = @[apnsConfig];
// generate the final pushPayload object
NSDictionary *pushPayload = [pushData dictionaryRepresentationFor:PNAPNS2Push|PNFCMPush];
NSLog(@"Notifications pushPayload: %@", pushPayload);
//publish on channel
[self.pubnub publish:payload toChannel:@"inbox.user123" mobilePushPayload:pushPayload
withCompletion:^(PNPublishStatus *status) {
NSLog(@"%@status '%@'", status);
}];
PushPayloadHelper pushPayloadHelper = new PushPayloadHelper();
// setup FCM parameters (FCMPayload)
PushPayloadHelper.FCMPayload fcmPayload = new PushPayloadHelper.FCMPayload();
PushPayloadHelper.FCMPayload.Notification fcmNotification =
new PushPayloadHelper.FCMPayload.Notification()
.setTitle("Chat invite")
.setBody("John invited you to chat");
fcmPayload.setNotification(fcmNotification);
// set FCM payload
pushPayloadHelper.setFcmPayload(fcmPayload);
// create the APS alert title/body
JsonObject apsAlertData = new JsonObject();
apsAlertData.addProperty("title", "Chat invite");
apsAlertData.addProperty("body", "John invited you to chat");
// define APS
PushPayloadHelper.APNSPayload.APS aps = new PushPayloadHelper.APNSPayload.APS()
.setAlert(apsAlertData)
.setSound("default");
PushPayloadHelper.APNSPayload apnsPayload = new PushPayloadHelper.APNSPayload()
.setAps(aps);
// Set APNS2 Configurations as a list
apnsPayload.setApns2Configurations(Arrays.asList(
new PushPayloadHelper.APNSPayload.APNS2Configuration()
.setVersion("v2")
.setTargets(Arrays.asList(
new PushPayloadHelper.APNSPayload.APNS2Configuration.Target()
.setEnvironment(PNPushEnvironment.PRODUCTION)
.setTopic("com.example.chat")
))));
// Set APNs payload
pushPayloadHelper.setApnsPayload(apnsPayload);
// Common payload for realtime PubNub subscribe
Map<String, Object> commonPayload = new HashMap<>();
commonPayload.put("text", "John invited you to chat");
commonPayload.put("room", "chats.room1");
pushPayloadHelper.setCommonPayload(commonPayload);
// Build the payload
// Returns a Map which can be used directly as the message for the pubnub.publish() method
Map<String, Object> payload = pushPayloadHelper.build();
System.out.println(payload);
//publish on channel
pubnub.publish()
.channel("inbox.user123")
.message(payload)
.async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
if (!status.isError()) {
System.out.println("pub timetoken: " + result.getTimetoken());
}
System.out.println("pub status code: " + status.getStatusCode());
}
});
The JSON below shows sample APNs payloads. For more details on APNs attribute usage, refer to the Apple Developer docs.
{
"pn_apns":{
"aps":{
"alert":{
"title":"Chat invitation",
"body":"John invited you to chat"
}
},
"pn_push":[
{
"push_type":"alert", //set to "alert", "background", "voip"
"targets":[
{
"environment":"production", //set to "development" or “production"
"topic":"BUNDLE_ID_FOR_APP_1" //set to the bundle id for your app
}
],
"version":"v2" //required
}
]
}
}
{
"pn_apns":{
"aps":{
"alert":{
"title":"Chat invite",
"body":"John invited you to chat"
},
"badge":2,
"sound":"melody"
}
}
}
The JSON below shows a sample FCM payload. For more details on FCM attributes go to Android FCM docs.
{
"pn_gcm":{
"notification":{
"title":"Chat invitation",
"body":"John invited you to chat",
"sound":"default"
}
}
}
Receiving Push Notifications
Once the PubNub Push Gateway sends the notification to APNs or FCM push providers, the notifications are delivered to the mobile device. Note that PubNub isn't involved in the actual delivery of the notification to each device—that is handled by the push providers.
If the user is active on the app they will receive the in-app message directly by subscribing to PubNub and a push notifications may not be necessary. For this, developers should actually mute the push notification within the didReceiveRemoteNotification
delegate instead of muting the realtime message from PubNub.
Subscribe vs Push
Subscribing to channels and registering for push notifications are two completely independent activities. When the client subscribes to a channel, it doesn't automatically receive push notifications for that channel. Similarly, registering for push notifications on channels doesn't mean the client will receive regular subscribe messages. Hence, it's common for a device to associate push notifications with the same channels that it subscribes to.
Excluding Devices in Publish
Sometimes it is desirable to exclude a device from a group push notification. For example, if a user has multiple devices registered to same channel and wants to send a group push notification they may want not to receive the same push on their own devices.
We support the pn_exceptions
parameter in the payload to handle this. The pn_exceptions
parameter accepts "device push tokens" (the same token used to register the device for push messages).
{
"pn_apns":{
"aps":{
"alert":{
"title":"Chat invitation",
"body":"John invited you to chat"
}
},
"pn_push":[
{
"push_type":"alert",
"targets":[
{
"environment":"production",
"topic":"BUNDLE_ID_FOR_APP_1"
}
],
"version":"v2" //required
}
],
"pn_exceptions" : [
"2643d955c7f2506e55f225b56da7eb8676cced80de93df51aad7569ee833b92f"
]
}
}
{
"pn_gcm":{
"notification":{
"title":"Chat invitation",
"body":"John invited you to chat",
"sound":"default"
},
"pn_exceptions" : [
"2643d955c7f2506e55f225b56da7eb8676cced80de93df51aad7569ee833b92f"
]
}
}
Mobile Push Troubleshooting
Read through Push Troubleshooting before attempting to do any troubleshooting so that you're aware of all the variables that could be at the root of the issue.