
benshi.ai Android SDK
Benshi Android SDK Setup
This documentation covers the steps to integrating SDK in your android apps. We’ll also discuss a few fundamentals of how the dashboard works in tandem with your app usage to view your users and engage them with contextually personalized messages.
There are two types of data we collect from the partner's side:
- content data (static content / items in the app)
- event data (event names, event details)
item data are static data of certain items (e.g. video, audio, a product, etc.). Event data is time-series data generated by the user.
Getting Started
The easiest way to integrate Benshi Android SDK in your Android project is with Maven Central. Add dependencies of Benshi Android SDK and Android Lifecycle Components in the app/build.gradle file.
dependencies {
// Benshi SDK
implementation 'ai.benshi.android.sdk:1.0.0'
//LifecycleComponents
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
}
Lifecycle components are required, if you already have them in your project you may skip them.
Initialization
Create an Application class in your project and include LifecycleObserver Components. Initialize Android SDK with your SDK Token from onCreate callback of your Application class as shown below.
class MyApplication : Application(), LifecycleObserver {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get()
.lifecycle.addObserver(this) // to observe Application lifecycle events
BenshiLog.init(applicationContext, appSDKToken) //init SDK with your SDK token
registerActivityLifecycleCallbacks(AppLifecycleTracker(applicationContext))
}
}
/*
In onAppStop() function include the following function to dispatch WorkManager to update app events collected offline or isUpdateImmediately false
*/
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppStop() {
BenshiLog.updateAppEvents(applicationContext) //this line
}
Benshi Android SDK also allows you to update track events after the user’s usage session is over. SDK sends the events whenever the app goes into background. This helps in not overloading the user’s phone while in use. SDK handles the events even in offline mode and ensures that they get uploaded to the portal whenever the user connects to the internet.
Don't forget to include android:name=".MyApplication"
in your manifest's application tag.
Add the following broadcast receivers in your app's manifest to listen for the app connectivity change and nudge feedback (opened/dismissed).
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NudgeActionReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NotificationOnCancelBroadcastReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NotificationOnClickBroadcastReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.GetNotificationService">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Android SDK - Event Tracking
Benshi Android SDK automatically starts tracking user data (e.g., Upload/download speed, OS version, device IDs) and engagement with the basic setup above. This data can be stored on the device and uploaded in batches to reduce network and power usage, and to increase the likelihood of successful uploads while you can also upload the events as soon as they happen. The upload is done when the user device session ends. SDK also starts tracking user sessions with this basic setup.
Each event can further be understood in the context of its attributes which includes details like time, upload/download speed, device details, locale, online/offline usage, screen time, interactions and so on. This enables you to gain in-depth insights into user interactions across your app. You can also leverage this data to segment users, personalize messages and configure campaign targeting.
Let’s take a look at the general structure of the attributes sent using that SDK:
Property Name | Reported on Portal | Description |
---|---|---|
User Id | u_id | User Id assigned in your Database, if you don’t have any signup/login process SDK defaults that to deviceID |
Device Id | d_id | User’s Device ID to uniquely recognise them |
OS | os | The current OS they are using. It is specified in {os.Name (os.Version)} e.g. android (30) Having the device OS and version help us to deliver content better presentable on their device. |
SDK Version | sdk_ver | Current SDK version you are using. |
Online Status | online | Tracks if the device was online or not when the event was recorded. |
Timestamp | ts | Track the timestamp of the event in RFC 3339 format |
Upload Speed | up | Track the upload speed of the device when the event was recorded |
Download Speed | down | Track the download speed of the device when the event was recorded |
Event Type | type | Type of event being tracked, use EventType class predefined events |
Event Name | name | Name of the event you are tracking |
Properties | props | Properties of the event being tracked. SDK provides predefined property models for you to integrate with ease. You can also track custom events too. |
For example, if a user needs to click on a product to view its details, then it is advisable to track this action as the event, product viewed as it brings them a step closer to making a purchase.
SDK events are divided into 3 main categories: User Events, System Events and Custom Events.
Tracking User Events
SDK automatically starts detecting the users across your platforms as soon as they're integrated. These visitors are classified as Unknown Users and Known Users.
Let's walk you through this:
Unknown Users
Each time a new user uses your app, they are tracked as anonymous users in your dashboard and an Unknown User Profile is created for them. The Android SDK automatically assigns them a unique ID (based on their device ID) and starts populating their user profile with all their data (System Events, Custom Events).
Known Users (Identity Events)
As and when the users share details that help you identify them in your platform, you can assign them a unique ID (Your Platform based UserId) to track them as Known Users. This user is now stored in our database as the ‘Identified/Registered’ ones. A new user profile is created for them that contains all their data from the previous anonymous user profiles, to be merged with the new account.
Known users have some user attributes as data points that provide information on what type of user they are. Such granular user data enables you to segment them into contextually relevant segments and personalize experience through all the channels of engagement (nudges). We have predefined several generic user details that all digital businesses can track for their users. These details are referred to as Known User Attributes. Here's a list of these attributes:
Identity Events | Data Type | What it Tracks |
---|---|---|
country | String | Country |
regionState | String | Region or State |
district | String | District |
city | String | City |
meta | Any | Used to include any other event related data, can be an object, string or number. |
Implementation
To Log identity events which involves events regarding the user of the app: signup, login or update user profile use: EventType.identify Identity log events are divided into 3 different types. For convenience, you can use IdentityType.{event name} in the log function. examples are:
- IdentifyType.register for new user (signup)
- IdentifyType.login for login (sign in)
- IdentifyType.update for updating user Profile (User Model)
SDK also provides a model/data class for the logging events in the required format.
val userObjectSDK = UserRegisterObject(
userId, //String
country, //String
region, //String
district, //String
city, //String
You can integrate SDK using 2 methods:
/*
Using function pattern, make sure to call `updateUserId` function before identity to update user id for logs
*/
BenshiLog.updateUserId(
appSDKToken, // Required - String - Token
userId, // Required - String
context //Required - Context
)
BenshiLog.track(
context //Required - Context
EventType.identify, // Required
IdentifyType.register.name, // Required
userRegisterObject // Optional - UserRegisterObject
)
/*
Using the Builder pattern, you don't need to call the `updateUserId` function as SDK will manage that.
*/
BenshiLogIdentifyEvent.Builder()
.init(this) //Required - Context
.setAppSdkToken(appSDKToken) //Required - String
.setAppUserId(userId) //Required String
.setIdentifyType(IdentifyType.register) //Required
.setCountry(country) //Optional - String
.setRegionState(region) //Optional - String
.setCity(city) //Optional - String
.setDistrict(district) //Optional - String
.build()
/*
You can also set use the Log event as:
*/
BenshiLogIdentifyEvent.Builder()
.init(this) //Required - Context
.setAppSdkToken(appSDKToken) //Required - String
.setAppUserId(userId) //Required String
.setIdentifyType(IdentifyType.register) //Required
.setUserRegisterObject(userObjectSDK) //Optional - UserRegisterObject
.build()
For updating user profile you can use the same identity event above but with IdentifyType.update
For Login event you can integrate any of the 2 ways:
/*
Using function pattern, make sure to call `updateUserId` function before identity to update user id for logs
*/
BenshiLog.updateUserId(appSDKToken, userId, this)
BenshiLog.track(this, EventType.identify, IdentifyType.login.name, null)
/*
Using the Builder pattern, you don't need to call the `updateUserId` function as SDK will manage that.
*/
BenshiLogIdentifyEvent.Builder()
.init(this) //Required - Context
.setAppSdkToken(appSDKToken) //Required - String
.setAppUserId(userId) //Required - String
.setIdentifyType(IdentifyType.login) //Required
.build()
Make sure to use IdentifyType.login
for login identity event.
Tracking System Events
We have pre-defined several generic actions that users can perform while interacting with your app. These actions are referred to as System Events that help in tracking elements on your app with user interaction. Some of these events are automated so that you don’t have to spend time integrating them.
Here's a list of System Events that can be tracked using predefined models for all your users:
Event Name | Calling in SDK | Description |
---|---|---|
Page | EventType.page | Track screen/activity changes and session timing. (Auto Tracked) |
Level | EventType.level | Track user experience |
Attempt | EventType.attempt | Track user attempts to complete a task |
Award | EventType.award | Track is user is awarded in the app |
Purchase | EventType.purchase | Track in-App purchases |
Scroll | EventType.scroll | Track scroll ratio and session length to know what interests them the most |
Message | EventType.message | Track any message shown to the user to design more interactive campaigns |
MessageAction | EventType.message_action | Track how the user responded to your campaigns |
Media | EventType.media | Track how your users interact with media to offer better |
SDK provides 2 ways to integrate System Events into your app. You can follow the function based approach where you need to include predefined models for event tracking or you can also use the builder pattern approach that will do the model mapping work for you.
Examples for above mentioned events with both approaches are given below:
Page Event
To Log page/screen change events you can use: EventType.page
By default SDK auto listens for Screen/Activity/Page changes in the app along with session timings that implicates how log a user spends on an activity but you can also log any specific event you want to track using below 2 approaches:
/*
Using function pattern, make sure to use the SDK defined `PageObject` for mapping elements.
*/
val pageObject = PageObject(
activity.packageName, // Required - String
activity.localClassName, // Required - String
duration, // Required - Double - Time in Nanoseconds user spend on that screen/activity/page
meta, //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, // Required - Context
EventType.page, // Required
activity.localClassName, // Required - String
pageObject, // Required
updateImmediately = false // Optional
)
/*
Using the Builder pattern, you don't need to use the `PageObject` function as SDK will manage that.
*/
BenshiLogPageEvent.Builder()
.init(context) //Required - Context
.setPageName(activity.localClassName) // Required - String
.setPath(activity.packageName) // Required - String
.setTitle(activity.localClassName) // Required - String
.setDuration(sessionLength.toDouble()) // Required - Double - Time in Nanoseconds, user spend on that screen/activity/page
.updateImmediately(false) //Optional - Boolean
.setMeta(meta) //Optional - Any [object, String, Int]
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Level Events
To Log Level change events you can use: EventType.level
/*
Using function pattern, make sure to use the SDK defined `LevelObject` for mapping elements.
*/
val levelObject = LevelObject(
levelNumber, //Required - Int
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.level, //Required
eventName, //Required - String
levelObject //Required,
)
/*
Using the Builder pattern, you don't need to use the `LevelObject` function as SDK will manage that.
*/
BenshiLogLevelEvent.Builder()
.init(context) //Required - Context
.setLevelName(levelName) // Required - String
.setLevelNumber(levelNumber) // Required - Int
.setTitle(activity.localClassName) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Attempt Events
To Log User Attempt events you can use: EventType.attempt
/*
Using function pattern, make sure to use the SDK defined `AttemptObject` for mapping elements.
*/
val attemptObject = AttemptObject(
awardID, //Required - String
success, //Required - Boolean
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.attempt, //Required
eventName, //Required - String
attemptObject //Required
)
/*
Using the Builder pattern, you don't need to use the `AttemptObject` function as SDK will manage that.
*/
BenshiLogAttemptEvent.Builder()
.init(context) //Required - Context
.setAttemptName(attemptName) // Required - String
.setAwardId(awardId) // Required - String
.setSuccess(isSuccessful) // Required - Boolean
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Award Events
To Log User Attempt events you can use: EventType.award
/*
Using function pattern, make sure to use the SDK defined `AwardObject` for mapping elements.
*/
val awardObject = AwardObject(
awardID, //Required - String
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.award, //Required
eventName, //Required - String
awardObject //Required
)
/*
Using the Builder pattern, you don't need to use the `AttemptObject` function as SDK will manage that.
*/
BenshiLogAwardEvent.Builder()
.init(context) //Required - Context
.setAwardName(awardName) // Required - String
.setAwardId(awardId) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Purchase Events
To Log User Purchase (In-app or Custom) events you can use: EventType.purchase
/*
Using function pattern, make sure to use the SDK defined `PurchaseObject` for mapping elements.
*/
val purchaseObject = PurchaseObject(
price, //Required - Double
currency, //Required - String
purchaseId, //Required - String
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.purchase, //Required
eventName, //Required - String
purchaseObject //Required
)
/*
Using the Builder pattern, you don't need to use the `PurchaseObject` function as SDK will manage that.
*/
BenshiLogPurchaseEvent.Builder()
.init(context) //Required - Context
.setItemName(purchaseItemName) // Required - String
.setPrice(price) // Required - Double
.setCurrency(currency) // Required - String
.setItemId(itemId) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Scroll Events
To Log User Scroll events you can use: EventType.scroll
Scroll events can be used with a scroll view, SDK provides methods to get scrollview content percentages that are currently visible to the user. You also need to get the session time (in nanoseconds) the user stayed on a specific screen.
To get Scroll Percentages you can use the SDK provided Utility method ScrollUtil.getScrollViewPercentageInt
by just passing the scrollview
itself.
For a detail preview on using scroll event, you can view ArticleActivity
in the demo app
val startScroll = ScrollUtil.getScrollViewPercentageInt(articleScrollView, //Required - scrollView
isStartScrollValue // Required - Boolean (For starting point set to 'true')
)
val endScroll = ScrollUtil.getScrollViewPercentageInt(articleScrollView, //Required - scrollView
isStartScrollValue // Required - Boolean (For end point set to 'false')
)
/*
Using function pattern, make sure to use the SDK defined `ScrollObject` for mapping elements.
*/
val scrollObject = ScrollObject(
startScroll.toDouble(), //Required - Double
endScroll.toDouble(), //Required - Double
sessionLength.toDouble() //Required - Double - Time in nanoseconds
)
BenshiLog.track(
context, //Required - Context
EventType.scroll, //Required
eventName, //Required - String
scrollObject, //Required
updateImmediately = false // Optional - Boolean
)
/*
Using the Builder pattern, you don't need to use the `ScrollObject` function as SDK will manage that.
*/
BenshiLogScrollEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setStartPercentage(startScroll) // Required - Double
.setEndPercentage(endScroll) // Required - Double
.setDuration(sessionLength) // Required - Double
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Message Events
To Log User Message events you can use: EventType.message
Message events can be used when you show any particular message to a user, a notification or an in-app message. For SDK fired nudges/in-app messages, you don't need to log this event as SDK will manage that itself.
/*
Using function pattern, make sure to use the SDK defined `MessageObject` for mapping elements.
*/
val messageObject = MessageObject(
notificationId, //Required - String
MessageType.push, //Required - MessageType.push, MessageType.in_app
title, //Required - String
content, //Required - String
"en", //Required - String - Language
messageActionList //Optional - ArrayList<MessageActionObject>
)
BenshiLog.track(
context, //Required - Context
EventType.message, //Required
eventName, //Required - String
messageObject //Required
)
/*
Using the Builder pattern, you don't need to use the `MessageObject` function as SDK will manage that.
*/
BenshiLogMessageEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setMessageId(messageId) // Required - String
.setMessageType(MessageType.push) // Required - Required - MessageType.push, MessageType.in_app
.setMessageTitle(title) // Required - String
.setMessageContent(content) // Required - String
.setMessageLanguage(language) // Required - String
.addMessageActions(messageActionsObject) // Optional - MessageActionsObject
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
/*
MessageActionsObject is used to store title for notification Action buttons (if any)
*/
val messageActionsObject = MessageActionsObject(
title //Required - String
)
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Message Action Events
To Log User Message/Notification Action events you can use: EventType.message_action
You can use message actions to track action items for the notifications. It can help you for having the log on what items on the notifications user most interacted with.
/*
Using the function pattern, make sure to use the SDK defined `MessageReactionObject` for mapping elements.
*/
val messageReactionObject = MessageReactionObject(
messageId, //Required - String
messageAction, //Required - String
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.message_action, //Required
eventName, //Required - String
messageReactionObject, //Required
updateImmediately //Optional - Boolean
)
/*
Using the Builder pattern, you don't need to use the `MessageReactionObject` function as SDK will manage that.
*/
BenshiLogMessageActionsEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setMessageId(messageId) // Required - String
.setMessageAction(messageAction) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Media Events
To Log User Media events you can use: EventType.media
You can use a media object to Track how your users interact with media items in your app. You can track the sessions they play a video and when they pause it. It can help you in coming up with a strategy to deliver media files in a way that is loved by your users.
/*
Using function pattern, make sure to use the SDK defined `MediaObject` for mapping elements.
*/
val mediaObject = MediaObject(
mediaId, //Required - String
MediaType.video, //Required - MediaType.video, MediaType.audio
MediaAction.start, //Required
duration //Required - Double
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.media, //Required
eventName, //Required - String
mediaObject //Required
)
/*
Using the Builder pattern, you don't need to use the `MediaObject` function as SDK will manage that.
*/
BenshiLogMediaEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setMediaId(mediaId) // Required - String
.setMediaType(MediaType.video) //Required - MediaType.video, MediaType.audio
.setMediaAction(MediaAction.start) // Required - MediaAction
.setTime(time) // Required - Double
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
MediaAction includes different types of media actions that can help you with logging desired events.
start, // Start playing media
pause, // Pause media playing
seek, // When user seeks the controller
finish, // Media finishes playing
playing, // Media is playing , auto play
stop, // User stopped playing, change in context
delete, // User deletes media
download, // User downloads media
For detailed implementation of the events, you can refer to QuestionActivity
in the demo app.
Tracking Custom Events
You can create Custom Events to track any other user interactions that are crucial for your business. Each Custom Event can further be defined by Event Attributes like event name, interact type, meta and so on. Such granular data enables you to engage users through highly contextual and personalized campaigns through nudges.
Here's a list of Custom Events that can be used based on your integration:
Event Name | Calling in SDK | Description |
---|---|---|
Interact | EventType.interact | Track User Interactions like click/tap, double tap, swipe, etc. |
Track | EventType.track | Track any event you want based on your models. |
SDK provides 2 ways to integrate Custom Events into your app. You can follow the function based approach where you need to include predefined models for event tracking or you can also use the builder pattern approach that will do the model mapping work for you.
Examples for above mentioned events with both approaches are given below:
Interact Events
To Log User Interact events you can use: EventType.interact
Interact events can be used to log events related to click listeners, swipes, double tap or long press.
/*
Using function pattern, make sure to use the SDK defined `InteractObject` for mapping elements.
*/
val interactObject = InteractObject(
InteractType.click, //Required - click, doubleclick, long press, swipe
eventName, //Required - String
meta //Optional - Any [object, String, Int]
)
BenshiLog.track(
context, //Required - Context
EventType.interact, //Required
eventName, //Required - String
interactObject, //Required
updateImmediately //Optional - Boolean
)
/*
Using the Builder pattern, you don't need to use the `InteractObject` function as SDK will manage that.
*/
BenshiLogInteractEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setActionType(InteractType.click) //Required - click, doubleclick, long press, swipe
.setElementName(elementName) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
Track Events
To Log User Track events you can use: EventType.track
You can use track events to log any custom events you want to log with SDK.
/*
Using function pattern, You can log custom interact details by passing your own params in the meta section.
*/
BenshiLog.track(
context, //Required - Context
EventType.track, //Required
eventName, //Required - String
meta, //Optional - Any [object, String, Int]
updateImmediately //Optional - Boolean
)
/*
Using the Builder pattern, you can track events. To log any specific data with a Track event you can use meta to log that. with .setMeta you can log any data type, object, string, integer or any other data Type. Another way is to use hashmap for key separated data.
*/
BenshiLogTrackEvent.Builder()
.init(context) //Required - Context
.setEventName(eventName) // Required - String
.setMeta(meta) //Optional - Any [object, String, Int]
.updateImmediately(false) //Optional - Boolean
.build()
updateImmediately
is default set to true
, you can use that to log events when the app goes in background or closed.
An example to use track method with hashmap is below:
val hashMap:HashMap<String, Any> = HashMap<String,Any>() //define empty hashmap
// Set key, value hashmap
hashMap.put("media_type",MediaType.image)
hashMap.put("media_action",MediaAction.upload)
hashMap.put("media_id",imageId)
hashMap.put("time",System.nanoTime().toDouble())
// log via BenshiLogTrackEvent
BenshiLogTrackEvent.Builder().init(context)
.setEventName("profile_image_upload")
.setMeta(hashMap).build()
Android SDK - Nudge Integration
With Nudges you can utilize experiment based data-driven insights and predictions for individual behaviors towards shaping strategies for collective behaviors. Nudges help you to interact with your users. You can use nudge to send push notifications, in-app messages or use other methods to interact with your users.
App publishers can send them at any time; even if the recipients aren’t currently engaging with the app or using their devices. You can start sending Push Notifications to your users via Benshi Portal by configuring Firebase Cloud Messaging (FCM).
Here's how you can go about it:
Add Firebase to Your Project
Ensure that all apps within a project are platform variants of the same application from an end-user perspective. It's advisable to register the iOS, Android, and web versions of the same app or game with the same Firebase project. All the apps in a project generally share the same Firebase resources (database, storage buckets, etc.).
If you have multiple build variants with different iOS bundle IDs or Android package names defined, you can register each variant with a separate Firebase project. However, if you have variants that share the same Firebase resources, register them with the same Firebase project.
Please follow these instructions for adding Firebase to Your Android Project.
Add Firebase Cloud Messaging Dependency
Add the dependency for Firebase Cloud Messaging in your module’s build.gradle.
dependencies {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.4.2')
// Declare the dependencies for the Firebase Cloud Messaging and Analytics libraries
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-messaging-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
}
Pass Firebase Token to SDK
Firebase tokens can be passed to SDK using FirebaseMessagingService
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token : String) {
BenshiLog.setFCMRegistrationID(token) // this one
}
}
It is also recommended that you pass Firebase token to SDK from onCreate of your Application class as shown below. This will ensure that changes in the user's Firebase token are communicated to the SDK.
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@OnCompleteListener
}
// Get new FCM registration token
val token = task.result
BenshiLog.setFCMRegistrationID(token) // this one
})
Pass Messages to SDK
By overriding the method FirebaseMessagingService.onMessageReceived, you can perform actions based on the received RemoteMessage object and get the message data. All incoming messages from Benshi Portal will contain key source
with the value as benshi
.
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val data: Map<String, String> = remoteMessage.getData()
if(data != null) {
if(data.containsKey("source") && "benshi" == data["source"]){
NudgeScheduler.showMessage(remoteMessage)
}
}
}
Next, register the service to the application
element of your AndroidManifest.xml
as follows.
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Add Your Firebase Credentials to Benshi Portal
Step 1: Log in to the Firebase Developers Console.
Step 2: Select your Firebase project.
Step 3: Navigate to Project Settings > Cloud Messaging and copy your server key as shown in the image below.
Step 4: Log in to your Benshi Portal as admin and navigate to Admin > Integrations > Nudge FCM Setup and Paste the copied server key under the field labeled FCM Server Key.
No further integration for nudge is required. SDK will manage the listeners and auto track the events involving user response to the nudge.
Guidelines
EventType
class is predefined in the SDK so make sure to use it to track any event.Custom Event Attributes
can be of these data types: String, Number, Boolean, Date, List, Map.EventName
is a required attribute and must be in a string format.Context
is required to pass with each log.updateImmediately
is an optional param, by default it’s value is true. You can decide for each event if it needs to be updated immediately or it can wait until the end of the app session.- Please ensure consistent usage of the names of Custom Events and their Custom Attributes across all your apps (Android, iOS) and website.
- In case you have an identity based app that requires signup/signin don't forget to call the following method in your signout function.
BenshiLog.releaseListeners(context) //Required - Context
- Nudge may not be delivered to apps which were put into background restriction by the user (such as via: Setting -> Apps and Notification -> [appname] -> Battery). Once your app is removed from background restriction, new messages to the app will be delivered as before. In order to prevent lost messages and other background restriction impacts, make sure to avoid bad behaviors listed by the Android vitals effort. These behaviors could lead to the Android device recommending to the user that your app be background restricted. Your app can check if it is background restricted using: isBackgroundRestricted() .
Please feel free to drop in a few lines at support@benshi.ai in case you have any further queries. We're always just an email away!



