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.

overview

Push flow

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

Overview

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:

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:

Callkit

Callkit

1.1 Creates 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: Callkit

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

Callkit

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.

Callkit

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

Callkit

Hit the Register button.

Callkit

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.

Callkit

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

Callkit

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.

Callkit

1.2.2 Configure Pushkit, Callkit in Flutter

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
Note:

Enable Push Notifications in Capabilities

Callkit

Callkit

Enable Voice over IP in Capabilities → Background Modes

Callkit Callkit

1.2.3 Register to receive notifications with Stringee server

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.

2. Set up for Android

2.1. Create the 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 the 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 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.

2.3. Set up FlutterFire to your app

In our sample, we're using FlutterFire to easier to get notifications from Firebase.

  1. Before any Firebase services can be used, you must first install the firebase_core plugin, which is responsible for connecting your application to Firebase. Add the plugin to your pubspec.yaml file:
    dependencies:
        firebase_core: "0.8.0-nullsafety.1"
  2. Install the plugin by running the following command from the project root:
    $ flutter pub get
  3. 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'
  4. 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());
    }
2.4. Device registration token

Retrieve the current registration token On initial startup of your app, the Firebase Cloud Messaging generates a registration token for the client app instance.

  1. First installation Firebase Cloud Messaging:

    • Add dependency:

      dependencies:
      firebase_messaging: "^8.0.0-dev.14"
    • Download dependency:

      $ flutter pub get
  2. When you need to retrieve the current token, call:

    import 'package:firebase_messaging/firebase_messaging.dart';
    ...
    FirebaseMessaging.instance.getToken().then((token) {
       print(token);
    });
  3. 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']));
    });
  4. 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.

2.5. Receive messages

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.

2.6 Display Notification

To show notification, in our sample we're using flutter_local_notifications:

  1. Install flutter_local_notifications:

    • Add dependency:
    dependencies:
    flutter_local_notifications: ^4.0.0
    • Download dependency:
    $ flutter pub get
  2. 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)
  3. 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:

      • Add the following attributes and permission to the activity you're opening in your 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">
      • then set 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,
            );
        }
      }
    );
    • If you want to cancel notification, call:
    _localNotifications.cancel(your nitification id);
2.7 Unregister the registration token.

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