Push, i.e., sending information from a server to a client without the client having initiated the communication itself in contrast to the standard model of request based interaction originating in the client, is widely used in a large variety of processes. XignIn as a technology also supports using push messages, for example to initialize an authentication without scanning a QR code.
While the concept of pushing messages to a receiving client can be implemented in different ways, one of the most reliable and energy efficient approaches for mobile devices is to utilize Google Firebase Cloud Messaging (FCM).
Therefore, the XignSys SDK and XignIn-Managers use this service to achieve a good user experience. The choice of utilizing FCM has implications on how to integrate push into an app, which will be discussed later on in this chapter.
Overall, this chapter explains how push can be utilized in the context of the XignSys SDK and a corresponding XignIn-Manager, gives an overview of the underlying processes and helps with the initial configuration as well as the implementation in apps using the XignSys SDK.
Attention:
While both the XignSys SDK and the XignIn-Managers support push in general given the minimum version requirements are met, it is important to know that the services users authenticate against have to be configured to support push as well. If, for example, a Website using XignIn technology for authentication purposes does not possess any business logic to enable push or the corresponding service is not allowed to utilize push for any reason, implementing push support in the app will not bring benefits for end users.
Structure of this chapter
Firstly, a description of the general process flow is given in the section General push message flow. Secondly, section Prerequisites explains what has to be done before push messages can be received, how the initial setup can be done and what configurations have to be completed. If all prerequisites are met and push messages can be received, using them to perform processes with the XignSys SDK requires use case specific implementations. Section Push Authentication Flow gives details on how push messages can be used to start an authentication process without scanning a QR code or performing any action on the device the app is being developed for. After that, section Push Cancellation Messages discusses use cases and necessary steps for cancellation messages that may be sent by the server in order to achieve a user-friendly push integration in implementing apps. Finally, section Incompatible Push Messages explains how to handle XignSys push messages that can not be properly processed by the SDK.
The underlying process is always the same when it comes to push messages with XignIn technology. First of all, some kind of trigger has to be activated in order to send push messages in a specific context. This trigger can be an external service that is connected to a XignIn-Manager and which starts a process such as an authentication via an API that the XignIn-Manager offers. Another trigger might be some kind of event during a process within the XignIn-Manager that causes push messages to be sent.
Whenever a trigger is activated, the corresponding XignIn-Manager needs to identify the accounts that should receive push messages. In case of the API exposed by the sever, the identifier is required as a parameter and can for example be an email address. Once the account is identified, the XignIn-Manager checks, amongst others, which devices the account owner has personalized at this moment and which devices have a push token configured on the server. If the XignIn-Manager decides the push message can be sent to these devices, it sends the use case specific messages to the FCM service which in turn handles the message delivery to each device.
In the implementing apps a handler has to be created that is invoked by the system. This configuration is platform dependent and explained in the sections Setup on Android and Setup on iOS respectively. Receiving push messages on a specific platform is always done in the same way and the messages themselves can potentially be sent by different services. Therefore, the message content has to be examined in order to determine how the app can proceed. In most cases, apps that currently are not in the foreground should create a notification that is presented to the end user and which opens the app on a click event.
Depending on the use case implemented by each service offering push messages, different approaches may be chosen with respect to the information contained in the messages. In order to maintain flexibility and to increase security, the XignSys SDK and corresponding XignIn-Manager use a specific protocol to exchange information via push. Not all relevant data for a process are always transmitted in the push message itself. Instead, push messages may contain the minimal set of information required by the SDK and server to determine which data has to be fetched from the server if users decide to act on the initial message. This way, most data is exchanged between the SDK and the server directly over an encrypted channel and without exposing too much data to Google or Apple.
For easier integration of the XignSys push functionality, raw push messages can be passed to the function
handleMessage(data:) in the helper class XignPush which analyzes and parses the content. If the message was
intended to be consumed by the XignSys SDK an instance of a XignPushMessageResult will be returned that can be used
according to its documentation to proceed.
Otherwise, if neither an error is raised nor a result object is returned, the push message was not sent in relation to
the XignSys SDK and must therefore be related to the app's own features. This way, XignPush can be used without first
filtering out push messages that are not intended for the XignSys SDK.
Currently, there are three different types of result objects potentially returned by the XignSys SDK:
XignPushMessageAuthentication is used to start an authentication process and can be passed to the function
Authenticator.fetchPushAuthenticationInitializationData or its synchronous counterpart.XignPushMessageCancel is used to denote a process should be aborted or previously created notifications that could
be used to start a process should be removed.XignPushMessageIncompatible indicates a push message was received that was intended to be handled by the SDK but
the process can not be executed for some reason.All results should be handled by the implementing app and are explained in more detail in their own subsections Push Authentication Flow, Push Cancellation Messages and Incompatible Push Messages respectively.
As already stated, the function XignPush.handleMessage(data:) only returns a result object if the message was
intended for the XignSys SDK and successfully parsed. In case the push message was not intended for the
XignSys SDK, the function will return null or nil respectively.
If it was indeed intended for the XignSys SDK but could not be parsed successfully, an error will be raised.
As usual, the embedded error code can be further examined to determine the root of the problem. Like for other
synchronous functions throughout the SDK, an error code mapper can be used for an easier handling of the actual
error codes that may occur during the function execution. In this particular case the mapper
XignPushHandleMessageErrorCodes.from(errorCode:) can be used for this purpose.
In order to successfully integrate push support in the implementing app there are a few prerequisites that must be met. This section explains the general requirements as well as platform specific steps necessary to implement push functionality properly.
Push is an optional feature provided by XignSys and so the SDK itself does not require the push module to be included as a dependency. Therefore, to integrate these features in the app, the appropriate dependency has to be declared explicitly. On both platforms, only one additional entry is required with respect to the XignSys SDK. FCM has its own dependencies though, which can not be controlled by XignSys GmbH.
These aspects have to be configured by a person or people that are allowed to manage firebase projects and/or the service(s) used to authenticate against in the XignIn-Manager.
First of all, a Firebase project is needed. If the implementing app already uses Firebase this project should be used.
It is possible to create multiple FirebaseApp instances at the same time for different Firebase projects.
However, this approach seems not to be fully supported by FirebaseMessaging and therefore may prove problematic in the
long run. If no Firebase project exists yet, the following link can be used to create a new
one Understand Firebase projects.
Secondly, the Firebase project that should be used must be made known to the XignIn-Manager. To do so, a Firebase Cloud Messaging API (V1) account must be created and added to the XignIn-Manager. This step requires privileged access on the XignIn-Manager, therefore please contact the designated service administrator.
For the final step a XignIn-Manager-Api-Key must be created, given the permission to send push messages and be linked with the XignIn-Manager service the authentication should be performed at. This step also requires privileged access on the XignIn-Manager.
Most use cases of receiving push messages also include showing some kind of information to the user in form of a notification, especially when the app receiving the message is not in foreground when the message is received. Note that the XignSys push implementation over Firebase only sends remote messages, meaning messages that will not be automatically displayed to the user as notifications via the Firebase SDK. Therefore, it is the implementing apps responsibility to prepare the received remote messages and inform the user.
In order to be able to show notifications to end users, these notifications not only have to be created based on the information received in a push message, but the user must also give consent to being shown such notifications. Both aspects are described in the respective platforms official documentation, e.g., iOS Asking Permission to Use Notifications and Android Notification runtime permission .
Please be aware that not all users want to receive notifications all the time and that, from a privacy perspective, it
may be a good approach to let the user opt in and out of this feature at any time. The XignSys SDK for example already
provides support on an activation level to add, update or remove push tokens with Personalizer.updatePushToken(token:)
and its synchronous counterpart, where an existing push token on the server is a prerequisite of receiving push messages
for this specific activation.
Given that the XignSys maven repository is already configured, only two additional entries have to be added in the
build.gradle.kts or build.gradle file. If the repository is not configured, i.e., the XignSys SDK is not integrated
in the app at all up to this point, please refer to the chapter
installation. Without an implementation
of the basic flows the SDK offers, integrating push can not be completed properly.
Besides the XignSys SDK Push Module the implementing app also needs to declare a dependency on the Firebase SDK.
From the Firebase SDK the module firebase-messaging is needed for the Firebase Cloud Messaging (FCM) functionality.
Furthermore, to be sure the most recent version is used, please refer to the official FCM documentation,
e.g., Firebase Android BoM (Bill of Materials).
Kotlin
In the modules build.gradle.kts or build.gradle file just add the following dependencies:
dependencies {
// XignSys SDK Push Module
implementation("com.xignsys:android-sdk-push-min24:5.0.0")
// FCM module
implementation("com.google.firebase:firebase-messaging:23.0.6")
}
Note: The XignSys SDK Push Module does not directly use any parts of the
firebase-messagingmodule and therefore does not declare a transitive dependency on this module to prevent possible future version conflicts. At the time of writing, theandroid-sdk-push-min24was tested in combination with the version 23.0.6 of thefirebase-messagingmodule.
Setting up Firebase Cloud Messaging (FCM) requires some steps to be performed. This includes the addition of the
"com.google.gms.google-services" plugin to the apps buildscript, as well as adding the "google-services.json" config
file, creating a FirebaseMessagingService, defining it in the apps manifest and handling notification permissions.
These steps are one example to set up Firebase within the app and may change in future version. To configure Firebase
correctly the official
documentation Set up a Firebase Cloud Messaging client app on Android
should be followed.
After the Firebase SDK has been successfully configured, the handling of the XignSys push messages can be implemented
within the function onMessageReceived(message: RemoteMessage) of the class that extends the FirebaseMessagingService
as described in the chapter Handling the result. The handling of the different messages will be
explained in detail in the following chapters as well as an implementation example given.
Given that the XignSys SDK Swift Package Manager (SPM) dependency is already configured, only two additional entries have to be added in the target that should integrate push. If the SPM dependency is not configured, i.e., the XignSys SDK is not integrated in the app at all up to this point, please refer to the chapter installation. Without an implementation of the basic flows the SDK offers, integrating push can not be completed properly.
To include the push module to the target, open the project settings, choose the target to modify and add a new entry
to the list of frameworks and libraries. The module should be selectable under the name XignSysSdkPush.
Besides the XignSysSdkPush module the implementing app also needs to declare a dependency on the Firebase SDK.
From the Firebase SDK the module FirebaseMessaging is needed for the Firebase Cloud Messaging (FCM) functionality.
The FCM SDK can be found under https://github.com/firebase/firebase-ios-sdk.git. Furthermore, to be sure the most
recent version is used and all other configurations are done properly, please refer to the official FCM documentation,
e.g., Setup FCM client app on Apple platforms.
Note: The
XignSysSdkPushmodule does not directly use any parts of theFirebaseMessagingmodule and therefore does not declare a transitive dependency on this module to prevent possible future version conflicts. At the time of writing, theXignSysSdkPushwas tested in combination with the version 9.2.0 of theFirebaseMessagingmodule.
Implementing different methods to receive push messages on iOS devices is not as flexible as on Android devices. Most products rely on Apples Push Notifications (APNs) when push messages have to be receivable even if the app is suspended or terminated, and FCM is no exception in this regard. Therefore, integrating XignSys push with FCM requires a few steps to be performed on iOS beforehand.
Capabilities
The app needs to have several capabilities in order to handle push properly. In the project settings, add the following capabilities to the target:
Push NotificationsTimeSensitiveNotifications (Optional)Furthermore, the app has to be allowed to process notifications when it is suspended, so make sure the checkbox for
Remote notifications under Background Modes is checked in the same target settings as well.
Apple Push Notifications configuration
In most cases FCM utilizes Apple Push Notifications (APNs) to provide the best user experience. Therefore, APNs has to be configured to integrate XignSys Push as well. Since APNs configuration may change over time and is independent of the XignSys use case, please refer to the official documentation, e.g., Registering your app with APNs .
After the FirebaseApp has been successfully initialized, the Firebase registration token must be made known to the
XignIn-Manager. This can either be done during the last step of the personalization, as described
in Finishing the Personalization, or by
invoking Personalizer.updatePushToken(idmIdentifier:token:). The latter requires that an activation has already been personalized.
Note that the push registration token must be updated for each personalization individually.
The function Personalizer.updatePushToken(idmIdentifier:token:) updates the push registration token stored on the XignIn-Manager,
which is needed to receive push messages. It can also be used to remove a stored token by passing nil / null. Beware
that the token can change, as mentioned in the official Firebase documentation. So it is the app responsibility update
the token if that happens. For more information about when this happens and on how to get the registration token, please
consult the official Firebase documentation,
Android: Access the device registration token
and
iOS: Access the registration token
.
The example below shows two simple functions to either update the existing push token and receive the currently used push token.
class PushTokenExamples {
private func updatePushToken(idmIdentifier: String, pushToken: String) {
XignSdk.shared.personalizer.updatePushToken(idmIdentifier, pushToken)
}
private func getCurrentPushToken(idmIdentifier: String) throws -> String? {
let idms = try XignSdk.shared.personalizer.getIdentityManagersSynchronous()
for idm in idms {
if (idm.identifier == idmIdentifier) {
return idm.pushToken
}
}
return nil
}
}
class PushTokenExamples {
private fun updatePushToken(idmIdentifier: String, pushToken: String) {
XignSdk.shared.personalizer.updatePushToken(idmIdentifier, pushToken)
}
private fun getCurrentPushToken(idmIdentifier: String): String? {
val idms = XignSdk.shared.personalizer.getIdentityManagersSynchronous()
idms.forEach {
if (it.identifier == idmIdentifier) {
return it.pushToken
}
}
return null
}
}
Important: As long as the Firebase registration token has not been made known to the server the app cannot receive any push messages.
XignSys push can be used to start an authentication process without requiring the end user to scan a QR code or click on an app-link/deep-link. Instead, some kind of trigger has to be invoked that leads to data being sent via push message to the users activated device(s). In most cases, this trigger is used by a service the end user wants to authenticate against directly. Utilizing push authentication for a service imposes some prerequisites to be met which are covered in Platform independent prerequisites.
Receiving an authentication push message
As for all push messages received from a XignIn-Manager, verifying the message and converting the relevant data to
a XignPushMessageResult is done by the helper function XignPush.handleMessage.
If a push message has not been sent by a XignIn-Manager, this function returns null/nil. But if it was and an error
occurred while processing the message, the function throws an appropriate error as well.
Upon receiving a XignPushMessageAuthentication result from the helper function, this result should be further
examined by the implementing app, before passing it over to the next function, e.g.,
Authenticator.fetchPushAuthenticationInitializationData(message:).
Retrieving information from an authentication push message result
Although receiving this object indicates a compatibility with respect to the push protocol, the app may not be able to
handle the authentication request at the current time. In such cases the property isIgnorable has to be checked,
which determines whether the information provided by the push message can be dropped silently or whether the end user
has to be informed about the situation.
Depending on the implementing app, a different handling may be desired with respect to the app being in the foreground while receiving the push message or being in the background, e.g., in a suspended state or closed completely. While in the latter case it is recommended, and somehow expected by end users that use push messages in other contexts, to build and show a notification to the user, in the former case the implementing app could decide on whether to display a notification as well, to present the relevant information to the user in another way or to start the according process right away.
In any case, the app has to retain at least the value of the property processId. This identifier should for example
be stored within the data for a user facing notification, since it is also used to cancel processes and remove the
respective notifications. This aspect is described in more detail in the section
Push Cancellation Messages.
Additionally, a XignPushMessageAuthentication has some properties that aid in informing the end user about the data
received via push message. The two optional String properties title and message are recommended to be used in
the form of choice to present data to the end user, like a notification or a dialog, if present, but the implementing
app can decide to ignore those properties and use other values instead.
Furthermore, the data received may be time sensitive and the XignIn-Manager, or sending party, may choose to give
additional hints on how to display the information regarding the visual representation. These hints are given by the
property priority which is of the enumeration type XignPushMessagePriority and indicate for example, which kind of
icon could be used in a notification based on that push message result.
Attention: Although a low or unspecified priority may be interpreted as the respective push message being irrelevant or negligible, this parameter is only a hint for displaying purposes. Whether acting on a received message can be postponed or the message has to be processed in a timely manner depends on the use case. For example, an authentication can in most cases only be performed in a specific time frame after a push message has been sent.
Building an authentication notification
When the relevant data is extracted from the result object and are saved in a way it can be accessed during an authentication process where needed, the decision has to be made on whether a notification should be built and shown to the user. If the app is not in the foreground, a notification should be built in any case, given the user gave consent to the app to do so.
Continuing the authentication
If an end user taps on a notification shown as a result of an authentication push message being received in a way the
app is triggered to proceed with said notification, the previously retained XignPushMessageAuthentication result
object can be passed to the function Authenticator.fetchPushAuthenticationInitializationData(message:) or its
synchronous counterpart. These functions fetch the data, that would otherwise for example be embedded in a QR code,
securely from the XignIn-Manager without exposing any critical information to FCM, Google or Apple. After receiving
the
AuthenticationInitializationData, handling the rest of the authentication does not differ from any other regular
authentication flow, i.e., the data can be passed to Authenticator.startAuthentication(data:requestCode) or its
synchronous counterpart. Details about these subsequent steps can therefore be read about in chapter
Authentication.
Most commonly, push messages in general are used to transport information for the user to be shown directly. But since push in the context of XignIn technology is mainly used to start processes, not cleaning up after such a process is started can lead to an unsatisfying user experience. After all, authentication processes have to be unique, and it would be both irritating for end users and insecure if an authentication could be performed on several devices simultaneously. Cleaning up as well as aborting a process for any reason can be achieved by utilizing cancellation messages.
For example, when an authentication has been initialized via push and the user has more than one device activated at that time, a notification informing the user about this authentication may be shown on these devices. If one of the notifications is used to proceed with the authentication on this particular device, the other devices do not inherently have the information about that process. Sending a cancellation message to said devices helps to prevent end users to try performing authentications that can not succeed anymore since they are already in process or even finished.
Receiving cancellation messages
As for all push messages received from a XignIn-Manager, verifying the message and converting the relevant data to
a XignPushMessageResult is done by the helper function XignPush.handleMessage.
If a push message has not been sent by a XignIn-Manager, this function returns null/nil. But if it was and an error
occurred while processing the message, the function throws an appropriate error as well.
Upon receiving a XignPushMessageCancel result from the helper function, this result should be further
examined by the implementing app.
This type of result object has three properties that have to be checked: isIgnorable, idmIdentifier and processId.
As with other results, the property isIgnorable indicates whether the information given by the push message can be
dropped silently in case the app is unable to act on it.
The idmIdentifier can be used to differentiate between XignIn-Managers the app may receive push messages from and
determine whether there is a current activation for this manager at all. One instance where this aspect may be
relevant, is a previously personalized app with the push feature activated (i.e., a current and valid push token is
still available in the XignIn-Manager) that is then reset without removing the push token beforehand.
With the cancellation of processes as the main purpose for this type of messages, the most important information
contained in them is what process to cancel which is represented by the value of the messages property processId.
While this value should be a unique ID with an extremely low probability for collisions, the idmIdentifier can also
be used as additional information to determine the process to cancel by matching both values with any previously
received values in other messages which processes are not completely completed yet.
In case an authentication message was received earlier and a notification is still being presented to the end user, this notification should be removed or replaced. Having a notification present that suggests the ability to start an authentication that has been triggered via push while this particular authentication process has already been started on a different device will irritate end users, since trying to perform such an authentication can not succeed. Nevertheless, notifications that show up and disappear later on automatically can also be a nuisance. Therefore, it could be a good idea to replace the original authentication notification with a new one that informs the user about this specific authentication to be cancelled, e.g., due to it being processed on another device.
Utilizing XignIn technology involves several actors and moving parts, e.g., the implementing app, XignSys SDK,
XignIn-Manager and services. Naturally, situations can emerge where communication protocols differ in version or other
incompatibilities occur. For this reason, the XignPush.handleMessage function can also return a
XignPushMessageIncompatible result.
As with other push message result types, the XignIn-Manager that sent the message can be identified with the value of
the
messages property idmIdentifier while the associated process is denoted by the property processId.
Also, the result carries the information whether it can be dropped silently or the user must be notified about the
incompatibility in isIgnorable.
While for other message result types the intent of the message is obvious, incompatibilities can occur in
different cases with respect to the original message type. Therefore, XignPushMessageIncompatible results hold
additional information on what kind of message the XignIn-Manager intended to send to the device in the
enumeration messageType as well as the minimum version of the protocol the XignSys SDK and XignIn-Manager use to
communicate with is required to process this message correctly in minSmartDeviceApi.
In most cases, the reason for an incompatibility is the protocol version, which means that the SDK has to be updated in order to support the feature associated with the push message or to be able to communicate with the XignIn-Manager in question at all.
The following examples show how received push messages can be handled. Note that the created notifications in this example are only for illustration purposes and should not be used in production as is. Furthermore, the example only shows the parsing of the push messages and creation of notifications. For the steps needed to take after a notification has been clicked, please refer to the corresponding subchapters of this part of the documentation.
// The AppDelegate of the application.
class PushExampleAppDelegate: UIResponder, UIApplicationDelegate {
// Override the function that handles remote notifications
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]
) async -> UIBackgroundFetchResult {
// optional - let the firebase SDK know that a new message has been received
Messaging.messaging().appDidReceiveMessage(userInfo)
do {
// try parsing the received push message
if let pushMessage: XignPushMessageResult = try XignPush.shared.handleMessage(userInfo: userInfo) {
// check the parsing result
switch pushMessage {
case .authentication(let message):
let xignPushMessageAuthentication: XignPushMessageAuthentication = message
// TODO - display a notification for the user, e.g. like:
let content = UNMutableNotificationContent()
content.title = xignPushMessageAuthentication.title ?? "Authentication"
content.body = xignPushMessageAuthentication.message ?? "Click to approve!"
if #available(iOS 15.0, *) {
content.interruptionLevel = .timeSensitive
}
// Store the `xignPushMessageAuthentication` within the notification,
// because it is needed to continue the process later on.
// Important: `userInfo` values must conform to `NSSecureCoding`, but `XignPushMessageAuthentication`
// does not! However, a `JSONEncoder` can be used as workaround because `XignPushMessageAuthentication`
// conforms to `Codable`.
content.userInfo["xignPushMessageAuthentication"] = try JSONEncoder().encode(
xignPushMessageAuthentication
)
let request = UNNotificationRequest(
// The process id can be used as identifier for the notification,
// so it can be canceled easily if needed
identifier: xignPushMessageAuthentication.processId,
content: content,
trigger: UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
)
try await UNUserNotificationCenter.current().add(request)
return .newData
case .cancel(let message):
let xignPushMessageCancel: XignPushMessageCancel = message
// TODO - cancel any still existing and presented notification, e.g. like:
UNUserNotificationCenter.current().removeDeliveredNotifications(
// Note: This cancellation will only work, if the process
// id was used as identifier for the notification
withIdentifiers: [xignPushMessageCancel.processId]
)
return .newData
case .incompatible(let message):
let xignPushMessageIncompatible: XignPushMessageIncompatible = message
// check if the user should be informed about the problem
if !xignPushMessageIncompatible.isIgnorable {
// TODO - display a notification informing the user about the situation
// If present, the type of the push message as well as the required protocol
// version can be checked to generate a more solution orientated notification.
xignPushMessageIncompatible.messageType
xignPushMessageIncompatible.minSmartDeviceApi
}
return .failed
}
} else {
// TODO - The message was not intended for the XignSys SDK - handled it by other means
return .noData
}
} catch {
// Check the type of the error. Note that the following example will produce a string for debugging
// purposes, in production however this error should be handled more end user friendly.
let errorMessage: String
if let xe = error as? XignSdkError {
// In case of a `XignSdkError` the general error code can be mapped to a more specific one, e.g. like:
switch XignPushHandleMessageErrorCodes.from(xe.errorCode) {
case .identityManagerNotPersonalized:
errorMessage = "XignIn-Manager not personalized."
case .invalidSignature:
errorMessage = "Invalid signature."
case .unexpectedError:
errorMessage = "Unexpected error:\n\(xe.message)"
}
} else {
errorMessage = "\(Swift.type(of: error)):\n\(error)"
}
// Display a notification
let content = UNMutableNotificationContent()
content.title = "Parsing push message failed!"
content.body = errorMessage
let request = UNNotificationRequest(
identifier: yourNotificationIdentifier,
content: content,
trigger: UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
)
try? await UNUserNotificationCenter.current().add(request)
return .failed
}
}
}
// The `FirebaseMessagingService` that handles the push massages for the application.
class PushMessagingService : FirebaseMessagingService() {
// Override the function that handles remote notifications
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
try {
// try parsing the received push message
val xignPushMessage: XignPushMessageResult? = XignPush.shared.handleMessage(data = message.data)
when (xignPushMessage) {
is XignPushMessageAuthentication -> {
// TODO - display a notification for the user, e.g. like:
val intent = Intent(applicationContext, YourActivity::class.java)
// Store the `xignPushMessageAuthentication` within the `Intent`,
// because it is needed to continue the process later on.
.putExtra("xignPushMessageAuthentication", xignPushMessage as Parcelable)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
val pendingIntent = PendingIntent.getActivity(
applicationContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val title = xignPushMessage.title ?: "Authentication"
val msg = xignPushMessage.message ?: "Click to approve!"
val builder = NotificationCompat.Builder(
applicationContext,
YOUR_NOTIFICATION_CHANNEL_ID
).setContentTitle(title)
.setContentText(msg)
.setStyle(NotificationCompat.BigTextStyle().bigText(msg))
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
// The process id can be used as identifier for the notification,
// so it can be canceled easily if needed
val processId = xignPushMessage.processId
NotificationManagerCompat.from(applicationContext).notify(
processId,
processId.hashCode(),
builder.build()
)
}
is XignPushMessageCancel -> {
// TODO - cancel any still existing and presented notification, e.g. like:
val tag = xignPushMessage.processId
// Note: This cancellation will only work, if the process
// id was used as identifier for the notification
NotificationManagerCompat.from(applicationContext).cancel(tag, tag.hashCode())
}
is XignPushMessageIncompatible -> {
// check if the user should be informed about the problem
if (!xignPushMessage.isIgnorable) {
// TODO - display a notification informing the user about the situation
// If present, the type of the push message as well as the required protocol
// version can be checked to generate a more solution orientated notification.
xignPushMessage.messageType
xignPushMessage.minSmartDeviceApi
}
}
null -> {
// TODO - The message was not intended for the XignSys SDK - handled it by other means
}
}
} catch (t: Throwable) {
// Check the type of the error. Note that the following example will produce a string for debugging
// purposes, in production however this error should be handled more end user friendly.
val errorMessage: String = if (t is XignSdkException) {
// In case of a `XignSdkException` the general error code can be mapped to a more specific, e.g. like:
when (XignPushHandleMessageErrorCodes.from(t.errorCode)) {
XignPushHandleMessageErrorCodes.IDENTITY_MANAGER_NOT_PERSONALIZED -> {
"XignIn-Manager not personalized."
}
XignPushHandleMessageErrorCodes.INVALID_SIGNATURE -> {
"Invalid signature."
}
XignPushHandleMessageErrorCodes.UNEXPECTED_ERROR -> {
"Unexpected error:\n${t.message}"
}
}
} else {
"${t::class.java.simpleName}:\n${t.message.toString()}"
}
// Display a notification
val builder = NotificationCompat.Builder(
applicationContext,
YOUR_NOTIFICATION_CHANNEL_ID
).setContentTitle("Parsing push message failed!")
.setContentText(errorMessage)
.setStyle(NotificationCompat.BigTextStyle().bigText(errorMessage))
.setAutoCancel(true)
NotificationManagerCompat.from(applicationContext)
.notify(YOUR_NOTIFICATION_ID, builder.build())
}
}
override fun onNewToken(token: String) {
super.onNewToken(token)
TODO("Handle token changes")
}
}