Using the Android App Messaging SDK
A tutorial for adding the Android App Messaging SDK code to your app to allow your app users to receive push notifications from your Dotdigital account
Our Android App Messaging SDK uses Firebase Cloud Messaging (FCM) to send push notifications to your Android app users. If you haven't already configured a Firebase project then please follow the instructions here first.
Our Android SDK is open source and can be found on Github here:
Basic sample apps can be found in Github here:
To embed in your native Android apps, complete the following tasks:
- Install the SDK
- Prepare the Push and Challenge handler classes
- Initialise the SDK
- Handle push message callbacks
- Optional: Change the icon or colour of your push notifications
- Starting a session
Handling asynchronous requestsYou can use either standard callbacks or observable streams to handle asynchronous requests. If you want to use observable streams, you need to add the RxJava library to your app. This tutorial explains how to use standard callbacks, but you can find a full sample of the RxJava code in the 'Android sample code' section.
Installing the SDK
- Add the App Messaging SDK to your module-level
build.gradlefile for Java orbuild.gradle.ktsfor Kotlin and change the minimum SDK version attribute to 21 and include the dependency forcom.comapi:foundationas shown in the snippets below:
defaultConfig {
...
minSdkVersion 21
...
}
Dependencies {
...
implementation 'com.comapi:foundation:1.6.0'
}android {
...
defaultConfig {
...
minSdk = 21
...
}
}
dependencies {
implementation("com.comapi:foundation:1.6.0")
...
}
Seeing a 'Manifest merger' error?The SDK has a minimum Android SDK version of 21, your app must support this also as a minimum level.
- Add the following dependencies to your top level build.gradle file:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.1'
}
}buildscript {
dependencies {
classpath("com.google.gms:google-services:4.4.1")
}
}- Add the following plugins to your module level build.gradle file:
plugins {
id "com.google.gms.google-services" version "4.4.1" apply false
}plugins {
id("com.google.gms.google-services") version "4.4.1" apply false
}- Copy the google-services.json file from your Firebase project into your apps root folder; this is used to configure your app to work with Firebase.
Sync NowRemember to synchronise
build.gradlefiles after making any changes.
Prepare the Push and Challenge handler classes
Before you can configure the Android SDK, you need the following:
- The value of the API space ID field in Dotdigital
- A class that creates a JWT token
- Create a placeholder push handler class which implements the
PushMessageListenerinterface to facilitate callbacks. The PushHandler is the class we passed instance of into the SDK init method. Inside we will get push messages delivered when the app is visible.
import com.comapi.internal.push.PushMessageListener;
import com.google.firebase.messaging.RemoteMessage;
public class PushHandler implements PushMessageListener {
@Override
public void onMessageReceived(RemoteMessage message) {
// TODO: Add push message handling such as displaying messages when in foreground and
// handling deep links and custom data
}
}import com.comapi.internal.push.PushMessageListener
import com.google.firebase.messaging.RemoteMessage
class PushHandler : PushMessageListener {
override fun onMessageReceived(message: RemoteMessage) {
// TODO: Add push message handling such as displaying messages when in foreground and
// handling deep links and custom data
}
}Initialising the Android SDK
Where to initialise the Android SDK in the activity lifecycleInitialisation needs to be performed in the
onCreate()of the AndroidApplicationclass so that your app users' profiles don't change every time they open the app. Remember to set that class in the manifest file<application android:name=".MyApplicationClass">
- After you've configured the SDK, import the
com.google.firebase.FirebaseAppclass into your file, and initialise the Firebase SDK.
FirebaseApp.initializeApp(this);FirebaseApp.initializeApp(this)
Firebase must be initialised before the SDKPlease ensure the
FirebaseApp.initializeApp(this);is called prior to initialising the SDK as it is a dependency of the SDK.
- Create a new instance of the
ComapiConfigclass, pass your API Space Id to theapiSpaceId()method, and an instance of the class that creates a JWT to theauthenticator()method using the snippet below:import com.comapi.ComapiConfig; ComapiConfig config = new ComapiConfig() // Set the id of the app space, the device belongs to .apiSpaceId("<API_SPACE_ID>") // Sets handler for authentication challenges (SDK asking for JWT token) .authenticator(new ChallengeHandler()) // When we are initialising the SDK in the Application class we will need to provide pushMessageListener to listen for push notification delivered when the app is visible to the user. // In which case Android won't display notification in the system tray. .pushMessageListener(new PushHandler());import com.comapi.ComapiConfig val config = ComapiConfig() // Set the id of the app space, the device belongs to .apiSpaceId("<API_SPACE_ID>") // Sets handler for authentication challenges (SDK asking for JWT token) .authenticator(ChallengeHandler()) // When we are initialising the SDK in the Application class we will need to provide pushMessageListener to listen for push notification delivered when the app is visible to the user. // In which case Android won't display notification in the system tray. .pushMessageListener(PushHandler())
You can set internal file logs, console logs, and network logs to the following levels. By default all log levels are set toConfiguring logs and proxy serversWARNING:OFFFATALERRORWARNINGINFODEBUGTo change the log levels, add the following line to theComapiConfigobject and use the appropriate method on theLogConfigobject:
You can also set a custom limit for the size of internal log files by calling the following method on the.logConfig(new LogConfig().setFileLevel(LogLevel.DEBUG).setConsoleLevel(LogLevel.INFO).setNetworkLevel(LogLevel.ERROR));.logConfig( LogConfig() .setFileLevel(LogLevel.DEBUG) .setConsoleLevel(LogLevel.INFO) .setNetworkLevel(LogLevel.ERROR) )ComapiConfigobject:If your app connects through a proxy server, add the following line to the.logSizeLimitKilobytes(limit);.logSizeLimitKilobytes(limit)ComapiConfigobject:.apiConfiguration(new APIConfig().proxy("http://xx.xxx.xx.xxx:xxxx"));.apiConfiguration(APIConfig().proxy("http://xx.xxx.xx.xxx:xxxx"))
- Pass the
ComapiConfigobject to one of the following initialisation methods. These methods return aComapiClientobject that you can use to access thesessionandprofileservices, which are used to create and update the user's profile.
- The
initialiseShared()method: When you use this method, the SDK stores theComapiClientobject, and you can access it at any time by calling theComapi.getShared()method (Java) or theRxComapi.getShared()method (RxJava) - The
initialise()method: When you use this method, you need to store theComapiClientobject yourself. ThegetShared()method is not available when you use this method.
package com.example.testapp;
import android.app.Application;
import com.comapi.Callback;
import com.comapi.Comapi;
import com.comapi.ComapiClient;
import com.comapi.ComapiConfig;
import com.google.firebase.FirebaseApp;
public class MyApplication extends Application implements Callback<ComapiClient> {
@Override
public void onCreate() {
super.onCreate();
FirebaseApp.initializeApp(this);
ComapiConfig config = new ComapiConfig()
// Set the id of the app space, the device belongs to
.apiSpaceId("<API_SPACE_ID>")
// Sets handler for authentication challenges (SDK asking for JWT token)
.authenticator(new ChallengeHandler())
// When we are initialising the SDK in the Application class we will need to provide pushMessageListener to listen for push notification delivered when the app is visible to the user.
// In which case Android won't display notification in the system tray.
.pushMessageListener(new PushHandler());
// Asynchronously initialise Foundation SDK client (retrieve it in callback).
// Shared makes ComapiClient accessible from Comapi.getShared()
// The last 'this' passed requires your class to implement Callback<ComapiClient> which will be invoked when the SDK has initialised
Comapi.initialiseShared(this, config, this);
}
// This is a callback for successful initialisation. We need to send a message to Activities
// that SDK is initialised and the client is available.
@Override
public void success(ComapiClient client) {
// SDK initialised
}
@Override
public void error(Throwable t) {
// Error when initialising SDK
}
}package com.example.testapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.comapi.Callback
import com.comapi.Comapi
import com.comapi.ComapiClient
import com.comapi.ComapiConfig
import com.google.firebase.FirebaseApp
class MainActivity : AppCompatActivity(), Callback<ComapiClient> {
override fun onCreate() {
super.onCreate()
// Init Firebase, must happen before the SDK init
FirebaseApp.initializeApp(this)
// Set the configuration for the SDK
val config = ComapiConfig()
// Set the id of the app space, the device belongs to
.apiSpaceId("<API_SPACE_ID>")
// Sets handler for authentication challenges (SDK asking for JWT token)
.authenticator(ChallengeHandler())
// When we are initialising the SDK in the Application class we will need to provide pushMessageListener to listen for push notification delivered when the app is visible to the user.
// In which case Android won't display notification in the system tray.
.pushMessageListener(PushHandler())
// Asynchronously initialise Foundation SDK client (retrieve it in callback).
// Shared makes ComapiClient accessible from Comapi.getShared()
// The last 'this' passed requires your class to implement Callback<ComapiClient> which will be invoked when the SDK has initialised
Comapi.initialiseShared(application, config, this)
}
// This is a callback for successful initialisation. We need to send a message to Activities
// that SDK is initialised and the client is available.
override fun success(client: ComapiClient) {
// SDK initialised
}
override fun error(t: Throwable) {
// Error when initialising SDK
}
}- Request permissions to receive and display push messages, see the functions below to achieve this; simply call
askPermission()in youronCreateevent handler, or when you would like to request the permission:// Starting from Android 13 (API level 33) we need a runtime permission to post notifications. // SDK manifest already includes POST_NOTIFICATIONS permission, but we also need to trigger a popup with permission request. // This is done with askPermission() method. You should handle the response from the popup as we have not shown this in this basic example. void askPermission() { if (Build.VERSION.SDK_INT >= 33) { if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { // Manifest.permission.POST_NOTIFICATIONS is available only if 'compileSdk 33' or greater requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 1); } } }// Starting from Android 13 (API level 33) we need a runtime permission to post notifications. // SDK manifest already includes POST_NOTIFICATIONS permission, but we also need to trigger a popup with permission request. // This is done with askPermission() method. You should handle the response from the popup as we have not shown this in this basic example. fun askPermission() { if (Build.VERSION.SDK_INT >= 33) { if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { // Manifest.permission.POST_NOTIFICATIONS is available only if 'compileSdk 33' or greater requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1) } } }
Handle push message callbacks
It is now time to flesh out the functionality of the push handler class which is called whenever the SDK receives a push message. Add the functionality as guided below:
Push handler callback
Within your push handler class that implements the pushMessageListener interface you'll need to decide what you want to do with the push notification and implement the logic by overriding the onMessageReceived() method. This method is called when a push notification is received while the app is in the foreground.
Functionality may include:
Displaying push notifications when the app is in the foreground
Push notifications are automatically displayed by Android only while the app is in the background. These notifications are sent to the system tray and launch your app when users tap them, but if you want to display the push notification message while the app is in the foregrounded, you will need to implement this.
You can extract the received push message body by calling message.getNotification().getBody() within your onMessageReceived handler.
Please see the official Android guidance for notifications to understand how to implement this, the example provided below is a basic implementation for illustrative purposes:
- Within your method you can retrieve the push message body by calling
message.getNotification().getBody()you can then display or store this as desired e.g.
package com.example.testapp;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import com.comapi.ComapiClient;
import com.comapi.internal.push.PushMessageListener;
import com.google.firebase.messaging.RemoteMessage;
import org.json.JSONException;
public class PushHandler implements PushMessageListener {
private final Context context;
public PushHandler(Context context) {
this.context = context;
}
@Override
public void onMessageReceived(RemoteMessage message) {
try {
ComapiClient.parsePushMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(context, MainActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
// Check if message contains a notification payload.
if (message.getNotification() != null) {
// Do something with the message to notify the user
// Example
createNotificationChannel(context);
Notification.Builder b = new Notification.Builder(context);
b.setAutoCancel(true)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("foreground message")
.setContentText(message.getNotification().getBody())
.setContentInfo("INFO")
.setContentIntent(resultPendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
b.setChannelId("test_channel_id1");
}
NotificationManager nm =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, b.build());
}
}
private void createNotificationChannel(Context context) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not supported in older libraries
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "test channel";
String description = "some description";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel =
new NotificationChannel("test_channel_id1", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}package com.example.testapp
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import android.content.Intent
import com.comapi.internal.push.PushMessageListener
import com.google.firebase.messaging.RemoteMessage
import com.comapi.ComapiClient
import org.json.JSONException
class PushHandler(private val context: Context) : PushMessageListener {
override fun onMessageReceived(message: RemoteMessage) {
try {
val result = ComapiClient.parsePushMessage(message)
} catch (e: JSONException) {
e.printStackTrace()
}
// Create an Intent for the activity you want to start
val resultIntent = Intent(context, MainActivity::class.java)
// Create the TaskStackBuilder and add the intent, which inflates the back stack
val stackBuilder = TaskStackBuilder.create(context)
stackBuilder.addNextIntentWithParentStack(resultIntent)
// Get the PendingIntent containing the entire back stack
val resultPendingIntent = stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
// Check if message contains a notification payload.
if (message.notification != null) {
// Do something with the message to notify the user
// Example
createNotificationChannel(context)
val b = Notification.Builder(context).apply {
setAutoCancel(true)
setDefaults(NotificationCompat.DEFAULT_ALL)
setWhen(System.currentTimeMillis())
setSmallIcon(R.drawable.ic_launcher_background)
setContentTitle("foreground message")
setContentText(message.notification?.body)
setContentInfo("INFO")
setContentIntent(resultPendingIntent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setChannelId("test_channel_id1")
}
}
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
nm.notify(1, b.build())
}
}
private fun createNotificationChannel(context: Context) {
// Create the NotificationChannel, but only on devices that have the Google API 26+ because
// the NotificationChannel class is new and not supported in older libraries
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name: CharSequence = "test channel"
val description = "some description"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel("test_channel_id1", name, importance).apply {
setDescription(description)
}
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}
}
}Handling deep links
The SDK is capable of handling deep links for you and tracking their usage, which is our recommendation.
If you want to trigger deep links within your own app to drive functionality then you will need to implement these in your app prior to sending them in a push, however you can always use a URL or invoke another apps deep links without needing to implement your own deep link schema.
To enable deep link handling you must do the following:
- For the app to understand which Activity it should open when myappscheme://mycustomhost link is invoked the activity declaration in AndroidManifest should have an intent-filter:
<activity
android:name=".MyActivity"
android:exported="true">
<intent-filter android:label="Open Activity in DotDigital Sample App">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "myappscheme://mycustomhost" -->
<data
android:host="mycustomhost"
android:scheme="myappscheme" />
</intent-filter>
</activity>- Your apps MainActivity needs to be adapted to ensure that any intents passed (onCreate, onNewIntent) to the app are checked to see if they are push messages so that the SDK can automatically track the usage in Dotdigital's analytics and invoke any deep links that are associated with the push action. In addition your app will need to request permission to invoke deep links in later versions of Android, so this needs to be done in the onCreate. The code required is shown below:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
askPermission();
ComapiClient client = Comapi.getShared();
handlePush(client, getIntent());
}
// If you use android:launchMode="singleTop" this will be the place where new intent for an existing activity will be delivered
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
ComapiClient client = Comapi.getShared();
handlePush(client, intent);
}
// Starting from Android 13 (API level 33) we need a runtime permission to post notifications.
// SDK manifest already includes POST_NOTIFICATIONS permission, but we also need to trigger a popup with permission request.
// This is done with askPermission() method. You should handle the response from the popup as we have not shown this in this basic example.
void askPermission() {
if (Build.VERSION.SDK_INT >= 33) {
if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// Manifest.permission.POST_NOTIFICATIONS is available only if 'compileSdk 33' or greater
requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 1);
}
}
}
// Handle push notification intents
void handlePush(ComapiClient client, Intent intent) {
if (client != null) {
// If we call client.handlePushMessage method providing the Activity context, intent that started the Activity,
// a boolean flag telling the SDK if it should open a deep link if it finds it and a callback,
// then the SDK will track the notification click interaction in Dotdigital analytics, optionally try to
// start an activity to open the deep link, and as a result will provide an object with:
// getUrl - Dotdigital deep link URL
// getData - Dotdigital custom data
// isTrackingSuccessful - was the click recorded in analytics
// isStartActivitySuccessful - was the activity associated with the deep link started
client.handlePushNotification(this, intent, true, new Callback<PushHandleResult>() {
@Override
public void success(PushHandleResult result) {
}
@Override
public void error(Throwable t) {
}
});
}
}
}class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
askPermission()
val client = Comapi.getShared()
handlePush(client, intent)
}
// If you use android:launchMode="singleTop" this will be the place where new intent for an existing activity will be delivered
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val client = Comapi.getShared()
handlePush(client, intent)
}
// Starting from Android 13 (API level 33) we need a runtime permission to post notifications.
// SDK manifest already includes POST_NOTIFICATIONS permission, but we also need to trigger a popup with permission request.
// This is done with askPermission() method. You should handle the response from the popup as we have not shown this in this basic example.
fun askPermission() {
if (Build.VERSION.SDK_INT >= 33) {
if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// Manifest.permission.POST_NOTIFICATIONS is available only if 'compileSdk 33' or greater
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
}
}
}
// Handle push notification intents
fun handlePush(client: ComapiClient?, intent: Intent) {
// If we call client.handlePushNotification method providing the Activity context, intent that started the Activity,
// a boolean flag telling the SDK if it should open a deep link if it finds it and a callback,
// then the SDK will track the notification click interaction in Dotdigital analytics, optionally try to
// start an activity to open the deep link, and as a result will provide an object with:
// url - Dotdigital deep link URL
// data - Dotdigital custom data
// isTrackingSuccessful - was the click recorded in analytics
// isStartActivitySuccessful - was the activity associated with the deep link started
client?.handlePushNotification(this, intent, true, object : Callback<PushHandleResult> {
override fun success(result: PushHandleResult) {
}
override fun error(t: Throwable) {
}
})
}
}Extracting a deep link
If you wish to extract a deep link URL so that you can choose how to handle it, you can use the parsePushMessage function to parse Dotdigital data for the URL or Firebase RemoteMessage (a helper method).
public class PushHandler implements PushMessageListener {
@Override
public void onMessageReceived(RemoteMessage message) {
try {
// Let the SDK parse the push payload
PushDetails result = ComapiClient.parsePushMessage(message);
// Get the deep link URL if available
Log.i("TEST", "url = " + result.getUrl());
} catch (JSONException e) {
e.printStackTrace();
}
}
}class PushHandler : PushMessageListener {
override fun onMessageReceived(message: RemoteMessage) {
try {
// Let the SDK parse the push payload
val result = ComapiClient.parsePushMessage(message)
// Get the deep link URL if available
Log.i("TEST", "url = ${result.url}")
} catch (e: JSONException) {
e.printStackTrace()
}
}
}Handling custom data payloads
The SDK can deliver custom data payloads via the push messages which your app can interpret to drive functionality. To access this custom data you will need to call the SDKs parsePushMessage() method with the contents of the push message. Any custom data can be extracted from the returned object by calling getData(). Add this code to your onMessageReceived() implementation in your push handler class. e.g.
public class PushHandler implements PushMessageListener {
@Override
public void onMessageReceived(RemoteMessage message) {
try {
// Let the SDK parse the push payload
PushDetails result = ComapiClient.parsePushMessage(message);
// Get the custom data using getData()
Log.i("TEST", "data = " + (result.getData() != null ? result.getData().toString() : "null"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}class PushHandler : PushMessageListener {
override fun onMessageReceived(message: RemoteMessage) {
try {
// Let the SDK parse the push payload
val result = ComapiClient.parsePushMessage(message)
// Get the custom data using getData()
Log.i("TEST", "data = ${result.data?.toString() ?: "null"}")
} catch (e: JSONException) {
e.printStackTrace()
}
}
}Changing the icon or colour of push notification
Our Android SDK uses Firebase Cloud Messaging (FCM) to send push notifications to your Android app users. As such, you can use the Android <meta-data> tag in your AndroidManifest.xml file to change the icon and colour of your push notifications.
<!-- Set icon used with incoming notification messages. This is used when no icon is set for the incoming notification message. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_launcher_round" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />Sessions
Starting a session
To receive push messages and register push tokens the SDK requires an active session.
To create a session you must have successfully initialized and retrieved a client object, you need to be able to identify the app user so that the sub claim in the JWT can be populated for the user; when the SDK requests the JWT in order to start the session. To create a session call:
client.service().session().startSession(new Callback<Session>(){/* implement */});client.service().session().startSession(object : Callback<Session> {
override fun success(session: Session) {
// implement
}
override fun error(t: Throwable) {
// implement
}
})rxClient.service().session().startSession()
.subscribe(new Observer<Session>(){/* implement */});rxClient.service().session().startSession()
.subscribe(object : Observer<Session> {
/* implement */
})Ending a session
You only have to end a session if you want to stop the app receiving push notifications, or you want to change users on the app.
To end the current session, call:
client.service().session().endSession(
new Callback<ComapiResult<Void>>(){/* implement */});client.service().session().endSession(object : Callback<ComapiResult<Void>> {
/* implement */
})rxClient.service().session().endSession()
.subscribe(new Observer<ComapiResult<Void>>(){/* implement */});rxClient.service().session().endSession()
.subscribe(object : Observer<ComapiResult<Void>> {
/* implement */
})
Only users that have both an email and push token will be created in DotdigitalPlease read the Registering your app users for push page to understand the requirements for syncing your app users with Dotdigital. Only users who have both an email address and a push token will be synced and eligible to receive push messages.
Next stepsNow ensure your app passes an email address to the SDK for the app user to ensure they get a contact created in Dotdigital by following these instructions
Want to know more about the SDK?To find out more about the SDK and its features and functions please go here
Updated about 9 hours ago
