Tutorial explaining how to implement Push Notifications on Parse
ACL | createdAt | objectId | updatedAt |
---|---|---|---|
There is no data in this class. |
Parse server is offering basic functionality of Push notification for Android, MacOS, iOS and tvOS. While the feature of push notification can let you:
Here are the steps to quick start push notification with parse server:
Firstly, we have to get some credentials from APNS and FCM to send push notifications. Let’s go with this: FCM for android Go to firebase console and navigate the project to get API key. To get this Key, you need to navigate to the project settings. Here in the tab of Cloud Messaging you will find the key labeled as Server key. APNS for iOS If you want to set up push notifications for iOS, macOS or tvOS, then you must know that there are different push certificate methods which parse server is supporting. These ways are given below: 1. Parse server is supporting the PFX (.p12) file which is exported from keychain access. 2. Parse server is also supporting token-based authentication too. 3. It can support key and push certificate in .pem format
You have to pass an additional configuration for Parse while initializing parse server. Have a look at the following example for this:
var server = new ParseServer({
databaseURI: '...',
cloud: '...',
appId: '...',
masterKey: '...',
push: {
android: {
apiKey: '...'
},
ios: {
pfx: '/file/path/to/XXX.p12',
passphrase: '', // optional password to your p12/PFX
bundleId: '',
production: false
}
}
});
While, format of configuration is:
push: {
android: {
apiKey: '' // The Server API Key of FCM
},
ios: {
pfx: '', // The filename of private key and certificate in PFX or PKCS12 format from disk
passphrase: '', // optional password to your p12
cert: '', // If not using the .p12 format, the path to the certificate PEM to load from disk
key: '', // If not using the .p12 format, the path to the private key PEM to load from disk
bundleId: '', // The bundle identifier associated with your app
production: false // Specifies which APNS environment to connect to: Production (if true) or Sandbox
}
}
While, if you want to go with a token-based authentication process than certificates then follow the following format:
push: {
ios: {
token: {
key: '/file/path/to/AuthKey_XXXXXXXXXX.p8',
keyId: "XXXXXXXXXX",
teamId: "YYYYYYYYYY" // The Team ID for your developer account
},
topic: 'com.domain.appname', // The bundle identifier associated with your app
production: false
}
}
However, to support both prod and dev certificates, you have to follow the configuration arrays as given below:
push: {
ios: [
{
pfx: '', // Dev PFX or P12
bundleId: '',
production: false // Dev
},
{
pfx: '', // Prod PFX or P12
bundleId: '',
production: true // Prod
}
],
tvos: [
// ...
],
osx: [
// ...
]
}
Configurations for tvOS and macOS also work similar to iOS. You just need to add additional configuration under appropriate key for both platforms. For tvOS key is tvos, while for macOS is osx. However, for dev and prod certificates, do the same as you have done above for all Apple platforms.
var server = new ParseServer({
databaseURI: '...',
cloud: '...',
appId: '...',
masterKey: '...',
push: {
android: {
apiKey: '...'
},
ios: {
pfx: '/file/path/to/XXX.p12',
passphrase: '', // optional password to your p12/PFX
bundleId: '',
production: false
},
osx: {
pfx: '/file/path/to/XXX.p12',
passphrase: '', // optional password to your p12/PFX
bundleId: '',
production: false
},
tvos: {
pfx: '/file/path/to/XXX.p12',
passphrase: '', // optional password to your p12/PFX
bundleId: '',
production: false
}
}
});
For parse server’s strategy for the list of certificates, then try them to match the installations, appidentifier, with bundleId. In case if you will be successful to find a certificate, then parse will use that certificate for connection establishment with APNS and will send push notifications. Otherwise, it will send you certificates.
Configure an application which you want to connect with the parse server. Send push notifications Currently, you can only send notifications with your master key via parse server and easiest way to do this is given below:
curl -X POST \
-H "X-Parse-Application-Id: you_app_id" \
-H "X-Parse-Master-Key: your_master_key" \
-H "Content-Type: application/json" \
-d '{
"where": {
"deviceType": {
"$in": [
"ios",
"android"
]
}
},
"data": {
"title": "The Shining",
"alert": "All work and no play makes Jack a dull boy."
}
}'\ http://your_server_address/parse/push
You can also use the following cloud code to send push notifications:
/ With promises
Parse.Push.send({
where: { ... },
data: { ... }
}, { useMasterKey: true })
.then(function() {
// Push sent!
}, function(error) {
// There was a problem :(
});
// With Legacy Backbone callbacks
Parse.Push.send({
where: query,
data: {
alert: 'Test',
badge: 1,
sound: 'default'
}
}, {
useMasterKey: true,
success: function() {
// Push sent!
},
error: function(error) {
// There was a problem :(
}
});
After this, see the push notifications being shown on your physical device. While, your parse log will look something like:
// FCM request and response
{"request":{"params":{"priority":"normal","data":{"time":"2016-02-10T03:21:59.065Z","push_id":"NTDgWw7kp8","data":"{\"alert\":\"All work and no play makes Jack a dull boy.\"}"}}},"response":{"multicast_id":5318039027588186000,"success":1,"failure":0,"canonical_ids":0,"results":[{"registration_id":"APA91bEdLpZnXT76vpkvkD7uWXEAgfrZgkiH_ybkzXqhaNcRw1KHOY0s9GUKNgneGxe2PqJ5Swk1-Vf852kpHAP0Mhoj5wd1MVXpRsRr_3KTQo_dkNd_5wcQ__yWnWLxbeM3kg_JziJK","message_id":"0:1455074519347821%df0f8ea7f9fd7ecd"}]}}
APNS Connected
APNS Notification transmitted to:7a7d2864598e1f65e6e02135245b7daf8ea510514e6376f072dc29d53facaa41
While, these logs mean your FCM and APNS connections have been established. Push Adapter Push adapters by parse server are actually abstracting the way to send push notifications. ParsePushAdapter is default implementation which is using APNS for iOS push and FCM for Android push. However, for any other push adapter you can implement your own option. However, for that you have to implement send(data, installations. After this, pass an instance like this:
var server = new ParseServer({
databaseURI: '...',
cloud: '...',
appId: '...',
masterKey: '...',
push: {
adapter: your_adapter
}
});
By doing this, parse server will decode your API and will run installation query with send(data, installations)of PushAdapter. Future improvement The current solution can be a good beginning for push notifications, but here we have some ideas for improvement: 1. More platforms support 2. Availability of more sending options 3. Support for more push providers. 4. Error handling and delivery report. 5. Scheduled pushes. 6. Benchmarking and job queue Silent notifications If your silent notification option is failing then check your payload. Make its setting to Int(1) for content-available. While, for APNs set background to push-type. Client configuration to receive push notifications Follow the following steps for this: Register your iOS device for push notifications Open up your AppDelegate.cs, AppDelegate.m or AppDelegate.swif and run the following function to register for remote notifications:
// Swift
let types: UIUserNotificationType = [.Alert, .Badge, .Sound]
let settings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
// Objective-C
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
// Xamarin
UIUserNotificationType notificationTypes = (UIUserNotificationType.Alert |
UIUserNotificationType.Badge |
UIUserNotificationType.Sound);
var settings = UIUserNotificationSettings.GetSettingsForTypes(notificationTypes,
new NSSet(new string[] { }));
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
// Handle Push Notifications
ParsePush.ParsePushNotificationReceived += (object sender, ParsePushNotificationEventArgs args) => {
// Process Push Notification payload here.
};
Handle UI and store device token for notifications as follows:
// Swift
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
print("Push notifications are not supported in the iOS Simulator.")
} else {
print("application:didFailToRegisterForRemoteNotificationsWithError: %@", error)
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
}
// Objective-C
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
}
// Xamarin
public override void DidRegisterUserNotificationSettings(UIApplication application,
UIUserNotificationSettings notificationSettings) {
application.RegisterForRemoteNotifications();
}
public override void RegisteredForRemoteNotifications(UIApplication application,
NSData deviceToken) {
ParseInstallation installation = ParseInstallation.CurrentInstallation;
installation.SetDeviceTokenFromData(deviceToken);
installation.SaveAsync();
}
public override void ReceivedRemoteNotification(UIApplication application,
NSDictionary userInfo) {
// We need this to fire userInfo into ParsePushNotificationReceived.
ParsePush.HandlePush(userInfo);
}
Compile and run these functions After configuring your application correctly, objects installation will be saved automatically when running app on parse server. Run the following curl command for verification:
curl -X GET \
-H "X-Parse-Application-Id: YOUR_APP_ID" \
-H "X-Parse-Master-Key: YOUR_MASTER_KEY" \
http://your_parse_server:1337/parse/installations
Proceed to step “send push notifications.” Push setup for android apps Add the following code in your root file “build.gradle”
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Now add the following library in your build.gradle project.
dependencies {
implementation "com.github.parse-community.Parse-SDK-Android:fcm:latest.version.here"
}
Register following services in the manifest:
<service
android:name="com.parse.fcm.ParseFirebaseInstanceIdService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Also register,
<service
android:name="com.parse.fcm.ParseFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Now this is the time of push broadcast receiver registration.
<receiver
android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
Customize your notifications Extend ParsePushBroadcastReceive to customize your notification with your own class. Register your device Add the following method in your application class’ onCreate method to create installation object.
// Native: Application.java
public void onCreate() {
// ...
ParseInstallation.getCurrentInstallation().saveInBackground();
}
// Xamarin: Application.cs
// IMPORTANT: Change "parsexamarinpushsample" to match your namespace.
[Application(Name = "parsexamarinpushsample.ParseApplication")]
class ParseApplication : Application {
// ...
public override void OnCreate() {
base.OnCreate();
// ...
ParsePush.ParsePushNotificationReceived += ParsePush.DefaultParsePushNotificationReceivedHandler;
}
}
Compile and run the code: After correct app configuration, installation objects will be saved automatically to your parse server. Use the following curl program for validation:
curl -X GET \
-H "X-Parse-Application-Id: YOUR_APP_ID" \
-H "X-Parse-Master-Key: YOUR_MASTER_KEY" \
http://your_parse_server:1337/parse/installations
Proceed to the step “run push notifications” This is the complete process to add push notification feature.