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 a Stringee push message.
Stringee supports Push Notification via Firebase Cloud Messaging (Android) and Voip Notification APNS(iOS). First, you get a 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:
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 in 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.
In this tutorial, we use Callkeep library to work with Pushkit and Callkit framework. You can check out their documentation for usage. Install Callkeep by definition as follows in your pubspec.yaml file. We use a fork version to add more functions:
callkeep:
git:
url: https://github.com/stringeecom/callkeep.git
ref: master
Enable Push Notifications in Capabilities
Enable Voice over IP in Capabilities → Background Modes
Setup Callkeep library
Future<void> configureCallKeep() async {
callKeep.on(CallKeepPushKitToken(), onPushKitToken);
callKeep.on(CallKeepDidDisplayIncomingCall(), didDisplayIncomingCall);
callKeep.on(CallKeepPushKitReceivedNotification(), didReceivePushNotification);
callKeep.on(CallKeepPerformAnswerCallAction(), answerCall);
callKeep.on(CallKeepPerformEndCallAction(), endCall);
callKeep.on(CallKeepDidPerformSetMutedCallAction(), didPerformSetMutedCallAction);
callKeep.on(CallKeepDidActivateAudioSession(), didActivateAudioSession);
callKeep.setup(<String, dynamic>{
'ios': {
'appName': 'Stringee',
},
'android': {
'alertTitle': 'Permissions required',
'alertDescription':
'This application needs to access your phone accounts',
'cancelButton': 'Cancel',
'okButton': 'ok',
},
});
}
When you receive a device token for Push Notification in CallKeepPushKitToken event, you need to register that token with Stringee server
InstanceManager.client.registerPush(pushToken, isProduction: false).then((result) {
bool status = result['status'];
String message = result['message'];
print('Result for resgister push: ' + message);
});
In which:
After register device token successfully with Stringee Server, you will receive CallKeepPushKitReceivedNotification event when you have an incoming call.
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 the 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 creating 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.
In our sample, we're using FlutterFire to easier to get notifications from Firebase.
pubspec.yaml
file:
dependencies:
firebase_core: "0.8.0-nullsafety.1"
$ flutter pub get
To allow Firebase to use the configuration on Android, the 'google-services' plugin must be applied on the project. This requires modification to two files in the android/
directory.
First, add the 'google-services' plugin as a dependency inside the android/build.gradle
file:
buildscript {
dependencies {
// ... other dependencies
classpath 'com.google.gms:google-services:4.3.3'
}
}
Lastly, execute the plugin by adding the following underneath the line apply plugin: 'com.android.application'
, within the /android/app/build.gradle
file:
apply plugin: 'com.google.gms.google-services'
Initializing FlutterFire Before any of the Firebase services can be used, FlutterFire needs to be initialized (you can think of this process as FlutterFire "bootstrapping" itself). The initialization step is asynchronous, meaning you'll need to prevent any FlutterFire related usage until the initialization is completed.
To initialize FlutterFire, call the initializeApp
method on the Firebase
class:
await Firebase.initializeApp();
The method is asynchronous and returns a Future
, so you need to ensure it has completed before displaying your main application. In our sample we put on main
before runApp
:
import 'package:firebase_core/firebase_core.dart';
...
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Platform.isAndroid)
Firebase.initializeApp().whenComplete(() {
print("completed");
});
runApp(new MyApp());
}
Retrieve the current registration token On initial startup of your app, the Firebase Cloud Messaging generates a registration token for the client app instance.
First installation Firebase Cloud Messaging:
Add dependency:
dependencies:
firebase_messaging: "^8.0.0-dev.14"
Download dependency:
$ flutter pub get
When you need to retrieve the current token, call:
import 'package:firebase_messaging/firebase_messaging.dart';
...
FirebaseMessaging.instance.getToken().then((token) {
print(token);
});
Register the registration token to Stringee Server
To receive a push notification, you must register the token to Stringee Server by calling:
import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart';
...
StringeeClient _client = StringeeClient();
...
FirebaseMessaging.instance.getToken().then((token) {
_client.registerPush(token).then((value) => print('Register push ' + value['message']));
});
Monitor token generation
To handle the creation, rotation, and updating of registration tokens, call:
Stream<String> tokenRefreshStream = FirebaseMessaging.instance.onTokenRefresh;
tokenRefreshStream.listen((token) {
_client.registerPush(token).then((value) => print('Register push ' + value['message']));
});
Make sure you call the registerPush
method to register the new token to Stringee server.
To receive messages from the background, call:
Future<void> _backgroundMessageHandler(RemoteMessage remoteMessage) async {
print("Handling a background message: ${remoteMessage.data}");
}
...
FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler);
Make sure Firebase.initializeApp()
is completed before receive message.
To show notification, in our sample we're using flutter_local_notifications:
Install flutter_local_notifications:
dependencies:
flutter_local_notifications: ^4.0.0
$ flutter pub get
Set up flutter_local_notifications:
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@drawable/ic_noti');
final IOSInitializationSettings iOSSettings = IOSInitializationSettings();
final MacOSInitializationSettings macOSSettings = MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(android: androidSettings, iOS: iOSSettings, macOS: macOSSettings);
await _localNotifications.initialize(initializationSettings, onSelectNotification: null)
Display a notification
Create channel for notification:
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id',
'your channel name',
'your channel description',
importance: Importance.max,
priority: Priority.high,
);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
if you want to show your app on lockscreen, do the following:
AndroidManifest.xml
:<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.USE_FULL_SCREEN_INTENT" />
...
<activity
android:showWhenLocked="true"
android:turnScreenOn="true">
fullScreenIntent: true
in your AndroidNotificationDetails
:const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
...
fullScreenIntent: true
);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
Show notification:
FlutterLocalNotificationsPlugin _localNotifications = FlutterLocalNotificationsPlugin();
...
await _localNotifications.initialize(
initializationSettings,
onSelectNotification: null,
).then((value) async {
if (value) {
/// Create channel for notification
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id',
'your channel name',
'your channel description',
importance: Importance.max,
priority: Priority.high,
fullScreenIntent: true, /// Set true for show App in lockScreen
);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
/// Show notification
await _localNotifications.show(
your notification id,
'your notification title',
'your notification body',
platformChannelSpecifics,
);
}
}
);
_localNotifications.cancel(your nitification id);
When you no longer want to receive a push notification from Stringee server, you must call:
_client.unregisterPush('deviceToken').then((value) => print('Unregister push ' + value['message']));
Now you complete the tutorial for push notification. You can view the completed sample on: stringee_flutter_sample