Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Push notifications integration with OneSignal

Camilo Castro edited this page Dec 4, 2020 · 24 revisions

OneSignal is a platform that let you send web push, mobile push, e-mails or in-app messages (discount panels, announcements, ...) through the Dashboard (manual) or the REST API for automated notifications.

At the end of this tutorial, you will be able to send global or targeted push notifications to the users of your Jasonette-made app.

Official website : https://onesignal.com/. With a free OneSignal account, you can register and send push notifications up to 30k devices.

If you want to implement notifications on both platforms (iOS + Android), I suggest you to first follow this tutorial beginning with Android configuration, ignoring all iOS/Apple steps and then read this a second time to integrate it for your iOS app.

1- Create accounts and prepare the work

1.1 - Create a OneSignal account (iOS + Android)

Create a OneSignal account by signing up here : https://app.onesignal.com/

1.2- Create an Apple Developer account and get a Push Certificate for your app (iOS only)

1.2.1- Create an Apple Developer account

Create an Apple Developer Account here : https://developer.apple.com/

1.2.2- Enroll in the Apple Developer Program

Once your account has been created, enroll in the Developer Program (99$/year at the time this article was redacted) : https://developer.apple.com/programs/enroll/

1.2.3- Add your app ID to your Apple Developer Account

Once enrolled, add your app identifier in the "Certificates, Identifiers & Profiles" section of your Apple Developer Account https://developer.apple.com/account/resources/identifiers/list

Click on the + blue button next to the "identifiers" title. On the next screen, select "App IDs" at the top of the page then click on "Continue". When asked for the type, choose "App". Then, fill the "description" textbox with a short description to easily retrieve this app in your Apple Developer Account. Next to "Bundle ID", select "Explicit" and fill the textbox with the Bundle ID you give to your app in Xcode (The unique one with reverse DNS style like : "com.jasonette.app"). Don't touch other values for now and save.

Congratulations, you have successfully linked your app to your Apple Dev Account, your app should now appear in your Apple Developer Account Dashboard.

1.2.4- Generate an iOS Push Certificate

Follow this doc to generate a Push Certificate from your Mac : Generate an iOS Push Certificate - OneSignal docs

For the 2nd step (Provisioning), the first method with the OneSignal's Automatic Provisioning Tool didn't work for me. I suggest you to directly jump to the second method to manually request the certificate.

1.3- Create a Google account and get a Firebase Server key for your app (Android only)

Create a Google account by accessing one of their services (Gmail for example)

Then, follow this doc to add a project in your Firebase Console and generate a Firebase Server Key : Generate a Firebase Server Key - OneSignal docs

2- Integrate OneSignal in your app

2.1- For Android (Android Studio)

Follow this doc to integrate OneSignal into your jasonette Android app : Android SDK Setup - OneSignal docs

Some tips :

  • Step 3.1 : Add the following piece of code in the "Launcher.java" file (under "app" -> "java" -> "com.jasonette.seed" -> "Launcher") :
// OneSignal Initialization
        OneSignal.startInit(this)
                .inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification)
                .unsubscribeWhenNotificationsAreDisabled(true)
                .init();

You can put this code just before the closing bracket (character "}") of the public void onCreate() { function. Don't forget to import com.onesignal.OneSignal; at the top of this same file.

  • You can stop at the end of Step 3. Perform Step 5 if you want compatibility for AndroidX.

2.2- For iOS (Xcode)

Follow this doc to integrate OneSignal into your jasonette iOS app : iOS SDK Setup - OneSignal docs

Some tips :

  • Step 3 : The name of your project must be "Jasonette", you can rename it later, after OneSignal integration : in the panel "Identity And Type" on the upper right corner in Xcode, the "Name" textbox must contains "Jasonette"
  • Step 3.2 : Don't perform step 3.2 because Jasonette already contains a custom Podfile
  • Step 3.6 : Previous steps didn't generate a new Workspace. you can continue opening your project by opening "Jasonette.xcworkspace"
  • Step 5 : You only need to copy-paste the lines between //START OneSignal initialization code and //END OneSignal initialization code in the "AppDelegate.m" file. Don't forget to also include #import <OneSignal/OneSignal.h> at the top of the file and to replace YOUR_ONESIGNAL_APP_ID by the app ID in your OneSignal Dashboard.
  • You can stop at the end of Step 5. If you want to test, you can perform Step 7.

3- Extend your Jasonette app to receive targeted notifications

At this point, your Jasonette App is able to receive global notifications (notifications sent to all app users) sent through OneSignal Dashboard or OneSignal API but not targeted push (you can not send notification to specific users).

To send notifications to specific/targeted users, we need a little more work. To understand what follows, we need to understand how OneSignal works and what we've done before :

In the previous steps, you have integrated OneSignal in your app. Now, when a user launch your app and accept push notifications (iOS only), the app sends a device-specific ID to OneSignal servers.

OneSignal is now aware that a new user has registered to push and can send notifications to his device because they previously received an ID attached to this device.

Now, what if you want to send a notification after an action has been done on YOUR server ? Easy ! OneSignal comes with a REST API, you can send a notification by simply sending a POST request with the user ID (Create notifications - OneSignal API docs. Examples in different languages at the end).

But yes, there is a problem : Your server has not attached an ID to a device and so can't target a specific user to send a notification to. To fix this problem, there is a simple solution which is to set an "external id" (OneSignal terminology).

You can set as "external id" everything that is used on your server to differentiate users (unique e-mail address, unique ID, unique username, ...). By following the steps below, you will extend Jasonette (See docs) by adding a new action.

This new action let you send an "external_id" to OneSignal servers. This "external id" will be linked with the OneSignal ID generated when openaing or accepting push notifs.

This action can be called in Jasonette like every other actions. It is defined like this :

"type": "$onesignal.set",
"options": { "externalid": "YOUREXTERNALID" }

Example : You implemented this action and call it every time a user log in your app in your JSON. The external ID you choose is the user e-mail address. The same user is running your App on an Android phone and an Ipad : The first times he opens the app on his Android phone, a OneSignal ID associated to his phone is sent to OneSignal servers. Then he logs in your app on his android phone. The action associate his mail address to the previously generated OneSignal ID. Every times he logs in your app, the externalid will be updated on OneSignal servers.

The first times he opens the app on his iPad, a OneSignal ID associated to his iPad is sent to OneSignal servers (it is not the same ID as the android phone). Then he logs in your app on his iPad. The action associate his mail address (which is the same) to the previously generated OneSignal ID.

So when you send a targeted notifications by externalid using the mail address of the user, the notification will be sent on the 2 devices associated with his externalid.

TODO : Reformulate paragraph : Need to be more concise.

3.1- Add $onesignal.set action on Android Studio

Under "app" -> "Java" -> "com.jasonette.seed" in the project browser, right click on the folder "Action" then click on "New" -> "Java Class". Name this new class "JasonOnesignalAction". Open the newly created "JasonOnesignalAction.java" and replace the whole content with the lines below :

package com.jasonette.seed.Action;

import com.onesignal.OneSignal;
import org.json.JSONObject;
import android.content.Context;
import com.jasonette.seed.Helper.JasonHelper;
import android.util.Log;

public class JasonOnesignalAction {

    public void set(final JSONObject action, JSONObject data, final JSONObject event, final Context context) {

        /*
         *  This function let you set the external onesignal id for the actual user
         *
         *            "type": "$onesignal.set",
         *            "options": {
         *              "externalid": "%id%",
         *            }
         */

        try {
            if (action.has("options")) {
                JSONObject options = action.getJSONObject("options");
                if(options.has("externalid")){

                    // REGISTER ID
                    String externalid = options.getString("externalid");
                    OneSignal.setExternalUserId(externalid);
                    JasonHelper.next("success", action, new JSONObject(), event, context);
                }
                else {
                    JSONObject err = new JSONObject();
                    err.put("message", "externalid is empty");
                    JasonHelper.next("error", action, err, event, context);
                }
            }
            else {
                JSONObject err = new JSONObject();
                err.put("message", "$onesignal.set has no options defined");
                JasonHelper.next("error", action, err, event, context);
            }
        } catch (Exception e) {
            Log.d("Warning", e.getStackTrace()[0].getMethodName() + " : " + e.toString());
        }
    }
}

Re build your app. And that's all. You are now able to setup externalid for this device using the following piece of code in your JSON app file :

"type": "$onesignal.set",
"options": { "externalid": "YOUREXTERNALID" }

3.2- Add $onesignal.set action on Xcode

Under "Jasonette" -> "Jasonette" in the project browser, right click on the folder "Actions" then click on "New Group". Name this group "$onesignal".

Right click on this new created "$onesignal" folder under "Actions" and choose "New File...". Create a new Header file (".h" extension) and name it "JasonOnesignalAction.h".

Replace all the content of this header file by the code below :

//
//  JasonOnesignalAction.h
//  Jasonette
//
//  Copyright © 2017 Jasonette. All rights reserved.
//
#import "JasonAction.h"
#import "JasonHelper.h"

@interface JasonOnesignalAction : JasonAction

@end

Again, right click on the "$onesignal" folder under "Actions" and choose "New File...". Create a new Objective-C File (".m" extension) and name it "JasonOnesignalAction.m".

Replace all the content of this Objective-C file by the code below :

//
//  JasonOnesignalAction.m
//  Jasonette
//
//  Copyright © 2017 Jasonette. All rights reserved.
//
#import "JasonOnesignalAction.h"
#import "JasonLogger.h"
#import <OneSignal/OneSignal.h>

@implementation JasonOnesignalAction

- (void)set{

    if (self.options) {
        NSString * externalid = self.options[@"externalid"];

        if (externalid) {
            DTLogInfo (@"Called $onesignal.set with options %@", self.options);
            [OneSignal setExternalUserId:externalid];
            [[Jason client] success];
        }
        else {
            [[Jason client] error];
        }
    }
    else {
        [[Jason client] error];
    }
}

@end

Re build your app. And that's all. You are now able to setup externalid for this device using the following piece of code in your JSON app file :

"type": "$onesignal.set",
"options": { "externalid": "YOUREXTERNALID" }

4 Limitations & action description

  • You can use the newly created "$onesignal.set" action as any other Jasonette actions.
  • The action succeeded if the externalid has correctly been updated
  • It returns an error if no "options" is defined under the "$onesignal.set" action
  • It also returns an error if the externalid value is empty

You must compile your iOS app for iOS version 10.0 minimum, otherwise OneSignal push won't work.

TODO : Add some images

Clone this wiki locally