Push Notification

This section explains how to set up push notification for each platform.

iOS

Dealing with Certificate

In order to enable push notification, you first have to generate p12 file from your Apple Push Certificate and then upload it to Channel through Channel Desk. (we support both development and production)

Obtain Apple Push Certificate

📘

Skip this step if you have already configured your app to support Apple Push Notification Service.

First, login to Apple Developer Center. Click Certificates, IDs & Profiles -> Identifiers -> App IDs, then select your App ID. By clicking Edit of your App ID, you will see something like this.

Follow the steps as described on the page (open Keychain Access -> Certificate Assistant -> Request a Certificate From a Certificate -> check on option Saved on disk -> upload it to the page you have processed). Download newly created certificate (.cer file) and double click to import it into your keychain.

Export the certificate

Launch Keychain Access and find the iOS Push Notification certificate for your application. You can verify the certificate is the correct one as it will start with "Apple (Development/Distribution) IOS Push Service:" followed by your application's bundle ID. Next, select both the certificate and private key, then right click and choose export 2 items.

Clicking Save will prompt you to enter password for your .p12 file. Enter the password then confirm and the p12 file will then be exported to the destination which you have designated.

Convert p12 to PEM

Once you save your p12 file, you need to execute following command line to get PEM from p12 file.

openssl pkcs12 -in push.p12 -out push.pem -nodes -clcerts

Upload your PEM file to Channel Desk

On your desktop, run Channel Desk and click Settings, and then go to Integrate mobile SDK Push section. Clicking iOS Integration button on top right corner will prompt a pop-up to upload your PEM file.

From there, upload the exported PEM file.

Back to react native

Before you actually add some codes into your project, make sure you use PushNotificationIOS provided by facebook. (If you haven't done yet, follow installation from link).

Request permission

import PushNotificationIOS from "@react-native-community/push-notification-ios";

PushNotificationIOS.requestPermissions();

Register token

import PushNotificationIOS from "@react-native-community/push-notification-ios";
import { ChannelIO } from 'react-native-channel-plugin';

PushNotificationIOS.addEventListener('register', (token) => {
  ChannelIO.initPushToken(token);
});

Handle push notification

import PushNotificationIOS from "@react-native-community/push-notification-ios";
import { ChannelIO } from 'react-native-channel-plugin';

PushNotificationIOS.addEventListener('notification', (notification) => {
  ChannelIO.isChannelPushNotification(notification.getData()).then((result) => {
    if (result) {
      ChannelIO.receivePushNotification(notification.getData()).then((_) => {
        notification.finish(PushNotificationIOS.FetchResult.NoData);  
      })
    } else {
      //other push logics goes here
      notification.finish(PushNotificationIOS.FetchResult.NoData); 
    }
  })
});

Add NativeCode to handle push on react-native

Because React-Native push handler can't handle push correctly without this settings, we need to add some code on native project.(This React-native-official-guide will help you.)

All blow guides are in above react offical link.

First, move ios folder in your ReactNative project. And Run ios native project(your_project_name. xcworkspace or your_project_name. xcodeproj)

Second, Open Appdelegate.h and Fix code

#import <UserNotifications/UNUserNotificationCenter.h>

  ...
  
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
  
  ...

Next, Open Appdelegate.m and add Code.

#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
  [ChannelIO initialize:application]
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;
 
 ....
}

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
 [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    if ([ChannelIO isChannelPushNotification:userInfo]) {
        [ChannelIO receivePushNotification:userInfo completion: ^{
            completionHandler(UIBackgroundFetchResultNoData);
        }];
        [ChannelIO storePushNotification: userInfo];
    } else {
        completionHandler(UIBackgroundFetchResultNoData);
    }
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
  [ChannelIO handlePushNotification:response.notification.request.content.userInfo completion:completionHandler];
  completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
 [RNCPushNotificationIOS didReceiveLocalNotification:notification];
}

Add Native code to handle open ChannelTalk when App closed

React-native-push-handler can't handle push click event correctly when app closed.
So you need to adding ChannelIO handlePushNotification function in didReceiveNotificationResponse of AppDelegate.m file

- (void)userNotificationCenter:(UNUserNotificationCenter *)center 
  didReceiveNotificationResponse:(UNNotificationResponse *)response  
  withCompletionHandler:(void (^)())completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;
    if ([ChannelIO isChannelPushNotification:userInfo]) {
        [ChannelIO receivePushNotification:userInfo completion: nil];
        [ChannelIO storePushNotification: userInfo];
    }
    completionHandler();
}

Open ChannelIO chat

If you want to move to the corresponding chat when when a user tap ChannelIO notification, handle push message by adding the following code in the last line of your App.js's componentDidMount() method.

import { ChannelIO } from 'react-native-channel-plugin';

componentDidMount() {
    ChannelIO.hasStoredPushNotification().then((result) => {
    if (result) {
      ChannelIO.openStoredPushNotification()
    }
  })
}

❗️

Maybe you need to add Notification Extension

When user or system terminate app, IOS block background task even if push received. So you maybe need to add additional code in Notification Extension.
If do not this, you can received push and sms together.

func application(_ application: didReceiveRemoteNotification userInfo: fetchCompletionHandler completionHandler:)
Above function sometimes do not called on app terminated. So we nee to use Notification Exention.

Extension Install Info: Notification Extension

Android

Set up Firebase project

Skip this step if you already have a firebase project for your application. You should download google-service.json and move the file into your Android app module root directory.

Register Server Key to Channel Desk

Move to ‘CLOUD MESSAGING’ tab and copy server key.

Once you copy the key, launch Channel Desk. Go to Settings and click ‘Integrate mobile SDK Push’.

Click ‘Android Integration’. Paste the server key you copied into API Key and click ‘add’.

Install dependencies

In your project & app build.gradle, you will need to add the following line to your dependencies:
Project build.gradle

dependencies {
    ...
    classpath 'com.google.gms:google-services:3.1.0'
    ...
  }

App build.gradle
Maven CentralMaven Central

dependencies {
    ...
    implementation 'io.channel:plugin-android-fcm:$[version]'
    ...
}
// you must add this code at the bottom
apply plugin: 'com.google.gms.google-services'

Integrating with existing FCM

Register token

To use Channel Plugin’s FCM in a project already using FCM, you should register token to ChannelIO as shown below.

import firebase from 'react-native-firebase';
import { ChannelIO } from 'react-native-channel-plugin';

componentDidMount() {
  this.onRefreshListener = firebase.messaging().onTokenRefresh(fcmToken => {
     ChannelIO.initPushToken(fcmToken);
  });
}

componentWillUnmount() {
  this.onRefreshListener();
}

Receive push notification

When onMessage() method is called, add following code to check whether the push notification is sent from ChannelIO.

import type { RemoteMessage } from 'react-native-firebase';
import { ChannelIO } from 'react-native-channel-plugin';

componentDidMount() {
  this.mListener = firebase.messaging().onMessage((message: RemoteMessage) => {
    ChannelIO.isChannelPushNotification(message.data)).then((result) => {
      if (result) {
        ChannelIO.receivePushNotification(message.data).then((_) => { })
      } else {
        // TODO : Your FCM code
      }
    }
  });
}

componentWillUnmount() {
  this.mListener();
}

Show push notification

If you want to move to the corresponding chat when when a user tap ChannelIO notification, handle push message by adding the following code in the last line of your App.js's componentDidMount() method.

import { ChannelIO } from 'react-native-channel-plugin';

componentDidMount() {
    ChannelIO.hasStoredPushNotification().then((result) => {
    if (result) {
      ChannelIO.openStoredPushNotification()
    }
  })
}