Session tracking
Session tracking captures the session which helps to keep track of the user activity in the app.
Client session tracking is enabled by default. It can be set through the TrackerConfiguration
as explained below.
- iOS
- Android (Kotlin)
- Android (Java)
let trackerConfig = TrackerConfiguration()
.sessionContext(true)
val trackerConfig = TrackerConfiguration("appId")
.sessionContext(true)
TrackerConfiguration trackerConfig = new TrackerConfiguration("appId")
.sessionContext(true);
When enabled, the tracker appends a client_session
entity to each event it sends and it maintains this session information as long as the application is installed on the device.
Sessions correspond to tracked user activity. User information is set via the Client session context entity.
A session expires when no tracking events have occurred for the amount of time defined in a timeout (by default 30 minutes). The session timeout check is executed for each event tracked. If the gap between two consecutive events is longer than the timeout the session is renewed. There are two timeouts since a session can timeout in the foreground (while the app is visible) or in the background (when the app has been suspended, but not closed).
The timeouts for the session can be configured in the SessionConfiguration
like in the example below:
- iOS
- Android (Kotlin)
- Android (Java)
let sessionConfig = SessionConfiguration(
foregroundTimeout: Measurement(value: 360, unit: .seconds),
backgroundTimeout: Measurement(value: 360, unit: .seconds)
)
Snowplow.createTracker(
namespace: "appTracker",
network: networkConfig,
configurations: [trackerConfig, sessionConfig]
)
val sessionConfig = SessionConfiguration(
TimeMeasure(6, TimeUnit.SECONDS),
TimeMeasure(30, TimeUnit.SECONDS)
)
Snowplow.createTracker(applicationContext, namespace, networkConfig, sessionConfig)
SessionConfiguration sessionConfig = new SessionConfiguration(
new TimeMeasure(6, TimeUnit.SECONDS),
new TimeMeasure(30, TimeUnit.SECONDS)
);
Snowplow.createTracker(getApplicationContext(), namespace, networkConfig, sessionConfig);
The lifecycle events (Foreground
and Background
events) have a role in the session expiration. The lifecycle events can be enabled as explained in App Lifecycle Tracking. Once enabled they will be fired automatically when the app moves from foreground state to background state and vice versa.
When the app moves from foreground to background, the Background
event is fired. If session tracking is enabled, the session entity will be attached to the event checking the session expiration using the foreground timeout.
When the app moves from background to foreground, the Foreground
event is fired. If session tracking is enabled, the session entity will be attached to the event checking the session expiration using the background timeout.
For instance, with this configuration:
- iOS
- Android (Kotlin)
- Android (Java)
SessionConfiguration(
foregroundTimeout: Measurement(value: 360, unit: .seconds),
backgroundTimeout: Measurement(value: 15, unit: .seconds)
)
val sessionConfig = SessionConfiguration(
TimeMeasure(360, TimeUnit.SECONDS),
TimeMeasure(15, TimeUnit.SECONDS)
)
SessionConfiguration sessionConfig = new SessionConfiguration(
new TimeMeasure(360, TimeUnit.SECONDS),
new TimeMeasure(15, TimeUnit.SECONDS)
);
the session would expire if the app is in background for more than 15 seconds, like in this example:
time: 0s - ScreenView event - foreground timeout session check - session 1
time: 3s - Background event - foreground timeout session check (3 < 360) - session 1
time: 30s - Foreground event - background timeout session check (30 > 15) - session 2
In the above example, the Foreground
event triggers a new session because the time spent in background (without tracked events) is bigger than the background timeout for the session.
Session callback
This feature is available since v3.1.
The tracker allows the configuration of a callback to inform the app every time a new session is created (in correspondence of a session timeout check).
This can be configured in the SessionConfiguration
and it provides the SessionState
where all the info already tracked in the session can be accessed.
Below is an example of where the session callback is used to print out the values of session every time a new session is generated by the tracker:
- iOS
- Android (Kotlin)
- Android (Java)
...
let sessionConfig = SessionConfiguration()
.onSessionStateUpdate { session in
print("SessionState: id: \(session.sessionId) - index: \(session.sessionIndex) - userID: \(session.userId) - firstEventID: \(session.firstEventId)")
}
...
let tracker = Snowplow.createTracker(namespace: kNamespace, network: networkConfig, configurations: [sessionConfig])
val sessionConfig = SessionConfiguration(
TimeMeasure(6, TimeUnit.SECONDS),
TimeMeasure(30, TimeUnit.SECONDS)
)
.onSessionUpdate { state ->
log(
"Session: " + state.getSessionId()
.toString() + "\r\nprevious: " + state.getPreviousSessionId()
.toString() + "\r\neventId: " + state.getFirstEventId()
.toString() + "\r\nindex: " + state.getSessionIndex()
.toString() + "\r\nuserId: " + state.getUserId()
)
}
Snowplow.createTracker(applicationContext, namespace, networkConfig, sessionConfig)
...
SessionConfiguration sessionConfig = new SessionConfiguration(
new TimeMeasure(6, TimeUnit.SECONDS),
new TimeMeasure(30, TimeUnit.SECONDS)
)
.onSessionUpdate(state -> log(
"Session: " + state.getSessionId()
+ "\r\nprevious: " + state.getPreviousSessionId()
+ "\r\neventId: " + state.getFirstEventId()
+ "\r\nindex: " + state.getSessionIndex()
+ "\r\nuserId: " + state.getUserId()
));
...
Snowplow.createTracker(getApplicationContext(), namespace, networkConfig, sessionConfig);
Decorating outgoing links using cross-navigation tracking
This feature was introduced in version 6.0.0 of the iOS and Android trackers.
The tracker provides a decorateLink
API to decorate outgoing links from the mobile app to another mobile app or to a website.
This API adds an _sp
parameter to the links containing information about the user, app, and current session.
This is useful for tracking the movement of users across different apps and platforms.
It is part of our cross-navigation solution and is equivalent to cross-domain tracking on the JavaScript tracker.
For example, calling decorateLink
on appSchema://path/to/page
will produce the following result:
appSchema://path/to/page?_sp=domainUserId.timestamp.sessionId.subjectUserId.sourceId.platform.reason
The decorateLink
function adds the following information to the link (configurable using the CrossDeviceParameterConfiguration
object passed to the method):
domainUserId
– The current tracker generated user identifier (value ofSessionController.userId
) – required.timestamp
– The current ms precision epoch timestamp – required.sessionId
- The current session identifier (value ofSessionController.sessionId
) – optional.subjectUserId
- The custom business user identifier (value ofSubjectController.userId
) – optional.sourceId
– TheappId
(value ofTrackerConfiguration.appId
) – optional.platform
- The platform of the current device (value ofTrackerController.devicePlatform
– optional.reason
– Identifier/information for cross-navigation – optional.
- iOS
- Android (Kotlin)
- Android (Java)
let link = URL(string: "https://example.com")!
let decoratedLink = Snowplow.defaultTracker()?.decorateLink(
link,
// optional configuration for which information to be added to the link
extendedParameters: CrossDeviceParameterConfiguration(sessionId: true, subjectUserId: true)
)
val link = Uri.parse("http://example.com")
val decoratedLink = Snowplow.defaultTracker.decorateLink(
link,
// optional configuration for which information to be added to the link
CrossDeviceParameterConfiguration(sessionId = true, subjectUserId = true)
)
Uri link = Uri.parse("http://example.com");
Uri decoratedLink = Snowplow.getDefaultTracker().decorateLink(link, new CrossDeviceParameterConfiguration(
true, // sessionId
true, // subjectUserId
false, // sourceId
false, // sourcePlatform
null // reason
));