Suggestions

close search

Push notification

When a Stringee call is made, Stringee Server pushes a message to the client who receives the call. If the client has already connected to Stringee Server, the incoming call can be received via onIncomingCall event and you can ignore the pushed message. Otherwise (the client disconnects from Stringee Server or the app is killed) the client only receives a message pushed from Stringee Server. Then the client must connect to Stringee Server to receive the incoming call.

This tutorial will walk you through the steps of integrating push notification into your app to receive Stringee push message.

Overview

Stringee supports Push Notification via Firebase Cloud Messaging (Android) and Voip Notification APNS(iOS). First you get registration token for Push Notification from Firebase or APNS. Then you call Stringee API to register this token to Stringee server. Follow these steps:

1. Setup for iOS

Callkit and Pushkit

The Callkit framework supports iOS 10 and above. Callkit lets Display the system-calling UI for your app's VoIP services, and coordinate your calling services with other apps and the system.

For more information, see Callkit

The Pushkit framework supports iOS 8.0 and above. Pushkit sends specific types of notifications such as VoIP invitations, watchOS complication updates, and file provider change notifications... It's very useful for VoIP apps. For more information, see Pushkit

With Callkit and Pushkit support, you can display an incoming call:

1.1 Create an iOS app on Stringee Dashboard.

Go to Stringee dashboard, choose Push Notification -> Choose your project -> Choose your existing app or create a new app.

Enter App name and Package name:

1.2 Configure Pushkit

1.2.1. Create an APNs Auth Key

To integrate push notification, you must upload an APNs Auth Key. When sending push notifications using an APNs Auth Key, we require the following information about your app:

To create an APNs auth key, follow the steps below.

Visit the Apple Developer Member Center

Click on “Certificates, Identifiers & Profiles”.

Go to Keys from the Left Menu.

Create a new Auth Key by clicking on the “+” button in the top right corner.

On the following page, add a Key Name, and select APNs

Hit the Register button.

On this page, you will be able to download your auth key file. Please do not rename this file, and upload it as it is to our dashboard, as shown later below.

Locate and copy your Team ID – click on your name/company name at the top right corner, then select “View Account”.

Copy Team ID. Then go to the iOS app on Stringee dashboard and upload the APNs Auth Key.

Click "Upload" button ==> Choose your APNs Auth Key, enter Key ID, Team Id ==> Upload.

1.2.2 Configure Pushkit, Callkit in react native

To use Pushkit in react native, there are 2 options:

In this tutorial, we use react-native-voip-push-notification to work with Pushkit framework.

And reactreact-native-callkeep to work with Callkit framework.

You can check out their documentation for usage.

npm install --save react-native-voip-push-notification
cd ios/ && pod install
npm install --save react-native-callkeep
cd ios/ && pod install
Note:

Enable Push Notifications in Capabilities

Enable Voice over IP in Capabilities -> Background Modes

1.2.3 Setup in ios native
AppDelegate.m Modification
1.2.4 Register to receive notifications with Stringee server

After using the RNVoipPushNotification.registerVoipToken function, you will receive a deviceToken from the listener. Send the token to the StringeeServer through the stringeeClient.registerPush function. For more information, see registerPush

const configVoipPush = () => {
  RNVoipPushNotification.addEventListener('register', token  => {
    setIosDeviceToken(token);
  });
  RNVoipPushNotification.registerVoipToken();
} 
const onConnect = (stringeeClient: StringeeClient, userId: string) => {
  stringeeClient.registerPush(
    iosDeviceToken,
    __DEV__, // isProduction
    true) // isVoip
      .then(() => {
         console.log('registerPush success');
      })
      .catch(console.error);
1.2.5 Show callkit when receive incoming call

When incoming call you can get 2 event:

When using Apple's VoIP service, whenever you receive an InComingCall event, you are required to display a call using the RNCallKeep library. To synchronize the call display with the events, you can do the following:

Report New Incoming Call from native
// --- Handle incoming pushes (for ios >= 11)

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
    NSDictionary *payloadDataDic = payload.dictionaryPayload[@"data"][@"map"][@"data"][@"map"];
    NSString *callId = payloadDataDic[@"callId"];
    NSNumber *serial = payloadDataDic[@"serial"];
    NSString *callName = fromAlias != nil ? fromAlias : fromNumber != nil ? fromNumber : @"Connecting...";
    if (serial == nil) {
        serial = @(1);
    }
    NSString *uuid = [RNStringeeInstanceManager.instance generateUUID:callId serial:serial];

    BOOL didShowCallkit = false;
    for (CXCall * call in callObs.calls) {
        if ([call.UUID.UUIDString.lowercaseString isEqualToString:uuid]) {
            didShowCallkit = true;
        }
    }
    if (!didShowCallkit) {
        [RNCallKeep  reportNewIncomingCall:uuid handle:@"Stringee"  handleType:@"generic"  hasVideo:**true**  localizedCallerName:callName supportsHolding:**false**  supportsDTMF:**true**  supportsGrouping:**false**  supportsUngrouping:**false**  fromPushKit:**true**  payload:**nil**  withCompletionHandler:completion];
    }
}
Report New Incoming Call from react native
const onIncomingCall(client: StringeeClient, call: StringeeCall) {
    call.initAnswer();
    call.generateUUID().then(uuid => {
        RNCallKeep.getCalls().then(items => {
            if (items.find(item => item.callUUID === uuid) == null) {
                RNCallKeep.displayIncomingCall(uuid, 'stringee', call.fromAlias, 'generic', call.isVideoCall);
            }
        })
    })
}

2. Set up for Android

2.1. Create API project

We're using Firebase Cloud Messaging (FCM) for push notification. So you must create a Firebase project in the Firebase console for Cloud Messaging projects. To create a FireBase project, go to https://console.firebase.google.com/

After creating a new FireBase project, add Firebase to your Android app

After adding app, download the google-services.json file.

2.2. Set up your project for push notification

Go to Firebase project console, choose Project Settings ==> General, you'll get the Firebase project id.

Go to Stringee Dashboard, choose Push Notification -> Choose your project -> Choose your app if existing or create new app -> Choose Android app then enter the Firebase project id, project package name.

After create your Android push notification app, redirect to Service accounts to generate your Firebase service account key.

You will receive a JSON file with a name like project_id-firebase-adminsdk-....json. Then upload your Firebase service account key.

2.3. Set up React Native Firebase to your app

We suggest using React Native Firebase to get notification from Firebase.

# Using npm
npm install --save @react-native-firebase/app

# Using Yarn
yarn add @react-native-firebase/app

Following this doc from React Native Firebase to config your project: https://rnfirebase.io/

# Install & setup the app module
yarn add @react-native-firebase/app

# Install the messaging module
yarn add @react-native-firebase/messaging

Following this doc from [Cloud Messaging])(https://rnfirebase.io/messaging/usage) to config your project: https://rnfirebase.io/messaging/usage

2.4. Device registration token

On initial startup of your app, the React Native FireBase generates a registration token for the client app instance. When you need to retrieve the current token, call:

import messaging from '@react-native-firebase/messaging';
...
messaging().getToken().then(token => {
  console.log('device token - ', token);
});

In order to receive push notification, you must register the token to Stringee Server by calling:

import {StringeeClient} from 'stringee-react-native-v2';
import messaging from '@react-native-firebase/messaging';
...
const stringeeClient = new StringeeClient();
...
const clientListener = new StringeeClientListener();
clientListener.onConnect = (stringeeClient, userId) => {
  messaging().getToken().then(token => {
    stringeeClient.registerPush(
      token,
      false,
      false)
      .then(() => {
      console.log('registerPush success');
      })
      .catch(console.error);
   });
};
...
stringeeClient.connect(access_token);

To handle the creation, rotation, and updating of registration tokens, call:

messaging().onTokenRefresh(token => {
   stringeeClient.registerPush(
      token,
      false,
      false)
        .then(() => {
          console.log('registerPush success');
        })
        .catch(console.error);
});

Make sure you call the registerPush method to register the new token to Stringee server.

2.5. Receive messages

To receive messages, add this in your class index.js :

import messaging from '@react-native-firebase/messaging';

...
// For receive from background state or quit state
messaging().setBackgroundMessageHandler(onMessageReceived);

See more from this doc: https://rnfirebase.io/messaging/usage#receiving-messages

2.6 Display Notification

When you successfully register to receive push and receive an incoming call. Stringee push notification data has the following format:

{
  stringeePushNotification = 1.0,
  data = {
  "callId" : "call-vn-1-QNQBY05CSE-1705021351841",
  "serial" : 1,
  "callStatus" : "started",
  "from" : {
    "number" : "user2",
    "alias" : "user2",
  },
  "to":{
    "number" : "user1",
    "alias" : "user1",
  },
  "projectId": 0000
},
type = CALL_EVENT
}

After receive a notification with callStatus is started, you can show your incoming call notification. To show notification, we suggest using Notifee:

<manifest ...>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> // Require for android 13 or above
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/> // For show in full screen mode
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> // For show notification over other app
        ...
        </manifest>

For show notification in android 13 or above, you must request the permission POST_NOTIFICATIONS for user to allow it, see more in android documentation.

# Using npm
npm install --save @notifee/react-native

# Using Yarn
yarn add @notifee/react-native

See more from this doc: https://notifee.app/react-native/docs/installation

After receive incoming call message from out server, you can show your custom notification. Here is a sample of a simple notification:

async function onMessageReceived(message) {
  const data = JSON.parse(message.data.data);
  console.log('data: ' + JSON.stringify(data));
  const callStatus = data.callStatus; // Status of call: started, ringing, answered, ended
  const from = data.from.number;
  const channelId = await notifee.createChannel({
    id: 'CHANNEL_ID',
    name: 'CHANNEL_NAME',
    description: 'CHANNEL_DESCRIPTION',
    vibration: true,
    importance: AndroidImportance.HIGH,
  });
  await notifee.displayNotification({
    id: 'NOTIFICATION_ID',
    title: 'Incoming Call',
    body: 'Call from ' + from,
    android: {
      channelId,
      importance: AndroidImportance.HIGH,
      category: AndroidCategory.CALL,
      autoCancel: false,
      ongoing: true,
      pressAction: {
        id: 'OPEN_APP_ACTION_ID',
          launchActivity: 'default',
        },
        actions: [
          {
            title: 'Answer',
            pressAction: {
              id: 'ANSWER_ACTION_ID',
              launchActivity: 'default',
            },
          },
          {
            title: 'Reject',
            pressAction: {
              id: 'REJECT_ACTION_ID',
            },
          },
        ],
      fullScreenAction: {
        id: 'OPEN_APP_IN_FULL_SCREEN_MODE_ACTION_ID',
        launchActivity: 'default',
      },
     },
  });
}
async function bootstrap() {
  const initialNotification = await notifee.getInitialNotification();
  if (initialNotification) {
    console.log('initialNotification', JSON.stringify(initialNotification.pressAction));
    if (initialNotification.pressAction) {
      // Open your call screen
      if (initialNotification.pressAction.id === ANSWER_ACTION_ID) {
        // button answer pressed
      }
    }
  } else {
    // Handle when app open in fullscreen mode
    if (StringeeCallManager.instance.call) {
      // Open your call screen
    }
  }
  await notifee.cancelNotification('NOTIFICATION_ID');
}

Note

stringeeClient.unregisterPush(token)
  .then(() => {
    console.log('unregisterPush success');
  })
  .catch(console.error);

Now you complete the tutorial for push notification. You can view the completed sample on: Sample