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.
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:
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:
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:
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:
Auth Key file
Team ID
Key ID
Your app’s bundle ID
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.
To use Pushkit in react native, there are 2 options:
Build native module for Pushkit.
Use third-party library.
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
Enable Push Notifications in Capabilities
Enable Voice over IP in Capabilities -> Background Modes
Import library
#import <PushKit/PushKit.h>
#import "RNVoipPushNotificationManager.h"
#import "RNCallKeep.h"
#import <RNStringeeInstanceManager.h>
Implement Pushkit framework
@implementation AppDelegate
...
/* Add PushKit delegate method */
// --- Handle updated push credentials
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
// Register VoIP push token (a property of PKPushCredentials) with server
[RNVoipPushNotificationManager didUpdatePushCredentials:credentials forType:(NSString *)type];
}
...
@end
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);
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:
// --- 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];
}
}
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);
}
})
})
}
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.
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.
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
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.
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
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');
}
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