Push Notifications

This section applies to Rebar only.

The setup steps closely follow the following tutorials:

Configuration

In .env specify:

PUSH_NOTIFICATIONS_PRODUCTION=true

or

PUSH_NOTIFICATIONS_PRODUCTION=false

to indicate whether the push notifications are configured for development or production.

Backend Setup for iOS

Creating an Explicit App ID

Every application installed on your device needs an App ID. As a convention, these are represented by reversed addresses (ex. com.example.MyParsePushApp). In order to support Push Notifications, your app must use an Explicit App ID.

In order to create a new Explicit App ID, do the following:

Registering an App ID
Enable Push Notifications

Configuring Push Notifications

Choose the newly created App ID from the list and select Edit, then scroll to the Push notifications section:

Configuring Push Notifications

Start by selecting Create Certificate under Development SSL Certificate. Then follow the instructions in the next screen to create a Certificate Signing Request (CSR) using the Keychain Access utility on your Mac. This will be used to authenticate the creation of the SSL certificate:

In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.

Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.

Creating a Certificate Signing Request (CSR)

Then Locate the CSR and upload it to Apple's servers, then click on Generate. Once the certificate is ready, download the generated SSL certificate to your Mac and save it as apns-dev.crt (or apns-prod.crt for production). This file will be used later in the process.

Once you download the certificate:

Export Certificate as .p12

Creating a provisioning profile

In order to run an app on an iOS device, a provisioning profile is required. Following the next steps to create it:

Setting up Apple Push Notification Service on the server

In the folder where the files apns-dev.cer and apns-dev.p12 created previously are saved, run the following commands:

openssl x509 -in apns-dev.cer -inform DER -outform PEM -out apns-cert-dev.pem
openssl pkcs12 -in apns-dev.p12 -out apns-key-dev.pem -nodes

or, alternatively for production:

openssl x509 -in apns-prod.cer -inform DER -outform PEM -out apns-cert-prod.pem
openssl pkcs12 -in apns-prod.p12 -out apns-key-prod.pem -nodes

When challenged with Enter Import Password press Enter. As a result, two files should be created:

or, for production:

Copy those to configuration/units/rb-push-notifications/server/.

Additional APNS configuration

iOS App

// ...
#import "RCTPushNotificationManager.h"
// ..

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // ...
}

// ...


// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
  [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification
{
  [RCTPushNotificationManager didReceiveRemoteNotification:notification];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
  [RCTPushNotificationManager didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  NSLog(@"%@", error);
}

// ...

Backend Setup for Android and Web

Creating a Google Project
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.rebar"
      android:versionCode="1"
      android:versionName="1.0">
      ...
Choose Project and Package Name

Google Cloud Messaging Server API Key and Sender ID

export var gcmSenderId = '123456789012'
export var gcmApiKey = 'ABCDEFGHKLMNQWERTYU-abc'
{
  "project_info": {
    "project_number": "1234567890",
    "project_id": "yourapp-319617"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:1234567890:android:8b1234567890",
        "android_client_info": {
          "package_name": "com.rebar"
        }
      },
      "oauth_client": [],
      "api_key": [
        {
          "current_key": "ABCDEFGHKLMNQWERTYU-abc"
        }
      ],
      "services": {
        "analytics_service": {
          "status": 1
        },
        "appinvite_service": {
          "status": 1,
          "other_platform_oauth_client": []
        },
        "ads_service": {
          "status": 1
        }
      }
    }
  ],
  "configuration_version": "1"
}

In /android/app/src/main/AndroidManifest.xml add the following:

<manifest ... >
  ...
  <application ...>
    ...
    <activity
      android:name=".MainActivity"
      ...
    >
      ...
      <intent-filter>
        <action android:name="codefoundries.action.NOTIFICATION" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </activity>
    ...
    <service android:name="com.evollu.react.fcm.MessagingService">
      <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
      </intent-filter>
    </service>
    <service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
      <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
      </intent-filter>
    </service>
  </application>
</manifest>
com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;

// ...

new ReactNativePushNotificationPackage(),

for instance:

// Should not be included import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;

// ...

// Should not be included new ReactNativePushNotificationPackage(),

Also, make the following additional changes (all changes shown combined below):

// ...
import com.evollu.react.fcm.FIRMessagingPackage;
// ...
// Should not be included import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
// ...

This needs to be done after every run of react-native link.

...
dependencies {
    compile 'com.google.firebase:firebase-core:10.0.0'
    compile 'com.google.firebase:firebase-messaging:10.0.0'
    ...
    // Should not be included    compile project(':react-native-push-notification')
    ...
}

XXX Create a task out of this!!!!

Usage

In order to send a push notification to all devices for a user, the sendNotificationToUser function can be used. Here is an example sending a message when a new To Do item is added:

import ObjectManager from '../../../graphql/ObjectManager'
import { sendNotificationToUser } from '../../../units/rb-push-notifications/server/notificationsServer'

export default function serverExtensions( router )
{
  ObjectManager.RegisterTriggerForAdd( 'ToDo', ( objectManager, newToDo ) =>
    sendNotificationToUser( newToDo.ToDo_User_id, newToDo.ToDo_Text +
      ' has been added to your To Do list', '/todo'
    )
  )
}