SDK

Remote Notifications

In this page you'll learn how notifications are handled in your app and what are all the options at your disposal to create a great messaging experience for your users.

Notificare supports several types of interactive and actionable notifications that will be handled for you without any extra development. If you are going to prevent this default behaviour, please note that you will have to either handle all the functionality yourself (metrics logging, presenting UI or collect replies) or if you don't, you understand that some features will not work as advertised.

Enabling Notifications

In order to enable the device to receive notifications, all that you need to do is invoke a single method.

await NotificarePush.enableRemoteNotifications();

Typically, the step above is done during some form of user onboarding. When the user already went through that flow, we can automatically enable notifications when the onReady event is triggered.

Notificare.onReady(async (application) => {
  if (await NotificarePush.isRemoteNotificationsEnabled()) {
    await NotificarePush.enableRemoteNotifications();
  }
});

As shown above, you can check if the user has previously enabled remote notifications. Additionally, you can check if the user has disabled notifications in the System Settings.

await NotificarePush.isAllowedUI();

Receiving Notifications

Authorization options

Our SDK allows you to define which notification's authorization options you would like to request from your user. This is an optional step, if not defined we will register UNAuthorizationOptions.alert, UNAuthorizationOptions.badge and UNAuthorizationOptions.sound by default. To define authorization options you can use the code below and customise as needed:

const availableOptions = [
  'alert',
  'badge',
  'sound',
  'carPlay',
  'providesAppNotificationSettings',
  'provisional',
  'criticalAlert',
  'announcement',
];

await NotificarePush.setAuthorizationOptions(availableOptions);

Also note that if you implement the UNAuthorizationOptions.providesAppNotificationSettings option, notifications from your app will display a button in both the Instant Tuning menu and Notification Settings. The purpose of that button is to provide users a shortcut to your app settings where they can fine-tune which kind of notifications they would like to receive. Implementing such settings views is highly recommended as it could be the reason between allowing your app to keep display notifications or being mute completely. If you do implement this option it is mandatory that you implement the following event:

NotificarePush.onShouldOpenNotificationSettings((notification) => {
  // Deep link to your settings view.
});

This will give you the opportunity to present your users with the in-app settings view where you should allow them to customize what kind of notifications they should receive. If the user clicked the button from a specific notification, you will receive that object too. When it comes from the Notification Settings, that object will be nil.

To know more about authorization options, please take a look at the native documentation.

Presentation options

Optionally, you can enable presentation options when your app is in the foreground. This will allow you to show a small banner on the top of your app, play a sound or badge your app, whenever a notification arrives, and your app is being used. By default, our library will set this to UNNotificationPresentationOptions = [], but you can change this behaviour to match your needs:

const availableOptions = [
  'alert',
  'badge',
  'sound',
  'banner',
  'list',
];

await NotificarePush.setPresentationOptions(availableOptions);

To know more about presentation options, please take a look at the native documentation.

Category options

If you are using Rich Push Templates you can define category options. These options can define how your notifications and actions will behave. To define category options you can use the code below and customise as needed:

const availableOptions = [
  'customDismissAction',
  'allowInCarPlay',
  'hiddenPreviewsShowTitle',
  'hiddenPreviewsShowSubtitle',
  'allowAnnouncement',
];

await NotificarePush.setCategoryOptions(availableOptions);

To know more about category options, please take a look at the native documentation.

Listening to Received Notifications

Once you're receiving notifications in your app, we can dive deeper and fully understand how they are handled. If you want to be notified incoming notifications, for example to add a badge to in your application, you can implement the following method.

NotificarePush.onNotificationReceived((notification) => {
  // more code ...
});

Presenting notifications

A notification can be opened by either tapping the actual notification or by tapping an action inside the notification. We will emit an event in each case.

NotificarePush.onNotificationOpened((notification) => {
  // more code ...
});

NotificarePush.onNotificationActionOpened((event) => {
  // more code ...
});

To handle the events above, you can take the managed approach and use our NotificarePushUI module which takes care of all the events and UI types as well as actions, or you can fully take over and present them however you prefer. However, be aware if you take the non-managed approach as you will have to deal with all aspects and types of presenting the notifications, including the events needed to show the user's engagement in our Dashboard.

For iOS, to handle all types of notifications, you need to make sure your app is declaring the following permissions in your app's Info.plist file:

ios camera privacy plist

You can add the following to your config.xml in order to get the result in the image above.

<platform name="ios">
  <config-file target="*-Info.plist" parent="NSCameraUsageDescription">
      <string>YOUR_RATIONALE</string>
  </config-file>

  <config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
      <string>YOUR_RATIONALE</string>
  </config-file>
</platform>

This will make sure your app can request access to the device's camera or photo library whenever it is needed.

The code below illustrates how this works when using the managed approach.

NotificarePush.onNotificationOpened(async (notification) => {
  await NotificarePushUI.presentNotification(notification);
});

NotificarePush.onNotificationActionOpened(async (event) => {
  await NotificarePushUI.presentAction(event.notification, event.action);
});

Additionally, when using the managed approach, you can listen to Notification lifecycle events and perform any additional steps you may require. You can listen to the following events as needed.

NotificarePushUI.onNotificationWillPresent((notification) => {
  // more code ...
});

NotificarePushUI.onNotificationPresented((notification) => {
  // more code ...
});

NotificarePushUI.onNotificationFinishedPresenting((notification) => {
  // more code ...
});

NotificarePushUI.onNotificationFailedToPresent((notification) => {
  // more code ...
});

NotificarePushUI.onNotificationUrlClicked((data) => {
  // more code ...
});

NotificarePushUI.onActionWillExecute((data) => {
  // more code ...
});

NotificarePushUI.onActionExecuted((data) => {
  // more code ...
});

NotificarePushUI.onActionNotExecuted((data) => {
  // more code ...
});

NotificarePushUI.onActionFailedToExecute((data) => {
  // more code ...
});

NotificarePushUI.onCustomActionReceived((data) => {
  // more code ...
});

For iOS, if you are considering supporting non-HTTPS pages when using the Webpage notification type you will need to also declare a more permissive ATS policy as follows:

declare ats in plist

You can add the following to your config.xml in order to get the result in the image above.

<platform name="ios">
  <config-file target="*-Info.plist" parent="NSAppTransportSecurity">
    <key>NSAllowsArbitraryLoads</key>
    <true/>
  </config-file>
</platform>

In modern apps, this is a great way of creating interactions between notifications, and your own app content, allowing you to send messages that can eventually drive the user to open content hidden deeper in your app.

To prepare your app to handle deep links is not complicated and will allow you to handle not only Deep Link notification types, but also any link made from a web page. In order to indicate your app that you will handle a custom URL scheme you simply have to configure the native part of your app to accept said URL schemes.

Declare the following in the config.xml and be sure to update the scheme to match yours:

<config-file target="AndroidManifest.xml" parent="/manifest/application/activity/[@android:name='MainActivity']">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="com.example" />
  </intent-filter>
</config-file>

If you are planning to handle Dynamic Links, you must also add all the domain prefixes you've created:

<config-file target="AndroidManifest.xml" parent="/manifest/application/activity/[@android:name='MainActivity']">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:host="demo.ntc.re" android:scheme="https"/>
  </intent-filter>
</config-file>

If you need to open external deep links in your notifications, you need to add the appropriate entries to your AndroidManifest.xml for those links to work in Android 11, for example to handle HTTP and HTTPS links, you would need to add the following to your config.xml:

<config-file target="AndroidManifest.xml" parent="/manifest">
  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
    </intent>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="http" />
    </intent>
  </queries>
</config-file>

Declare the following in your config.xml and be sure to update the properties to match yours:

<config-file target="*-Info.plist" parent="CFBundleURLTypes">
  <array>
    <dict>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>com.example</string>
      </array>
    </dict>
  </array>
</config-file>

If you are planning to handle Dynamic Links, you must also add all the domain prefixes you've created:

<config-file target="Entitlements-*.plist" parent="com.apple.developer.associated-domains">
  <array>
    <string>applinks:demo.ntc.re</string>
  </array>
</config-file>

Another common example where you will make use of deep links, would be to take proper action whenever users click in hypertext links in a Notificare's HTML or Web Page notification type. This is done by first declaring all the URL schemes that you want to handle.

In your config.xml:

<platform name="android">
  <config-file target="AndroidManifest.xml" parent="/manifest/application">
    <meta-data
      android:name="re.notifica.push.ui.notification_url_schemes"
      android:resource="@array/notification_url_schemes" />
  </config-file>

  <resource-file src="notification_url_schemes.xml" target="/app/src/main/res/values/notification_url_schemes.xml" />
</platform>

This entry will require you to create a notification_url_schemes.xml file in the root of your project with the following content:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="notification_url_schemes">
    <item>com.example</item>
    <item>com.example2</item>
    <item>com.example3</item>
  </string-array>
</resources>

In your NotificareOptions.plist:

<plist version="1.0">
  <dict>
    <key>URL_SCHEMES</key>
    <array>
      <string>com.example</string>
      <string>com.example2</string>
      <string>com.example3</string>
    </array>
  </dict>
</plist>

Any click in an HTML or Web Page notification type, would be intercepted by our library and trigger the event NotificarePushUI.onNotificationUrlClicked.

Inbox

With our library it's extremely easy to implement an in-app inbox. Implementing an inbox increases considerably the engagement rate of your notifications simply because messages will always be available inside your app. To activate the inbox functionality, please follow the instructions described here.

After activating this functionality, you can start implementing an inbox on your app. The inbox is available via the NotificareInbox module. The inbox is exposed via events from NotificareInbox, so it is really easy to hook up your view controller to a list of inbox items, for example:

NotificareInbox.onInboxUpdated((items) => {
  // Do something with the items.
});

In the same way, you can listen for the number of unread messages.

NotificareInbox.onBadgeUpdated((badge) => {
  // Do something with the badge.
});

If you want to get the data at any point in time, you can still get the items and the badge in the inbox.

// Items
const items = await NotificareInbox.getItems();

// Badge
const badge = await NotificareInbox.getBadge();

Managing inbox items

Assuming that you hold a reference to an item, to open an inbox item you would simply do something like this:

const notification = await NotificareInbox.open(item);

To remove items from the inbox you would invoke the following method:

await NotificareInbox.remove(item);

Additionally, you can also mark a message as read by invoking the following method:

await NotificareInbox.markAsRead(item);

Or mark all messages as read by invoking the following method:

await NotificareInbox.markAllAsRead();

To remove all items in the inbox you would do the following:

await NotificareInbox.clear();