Link Search Menu Expand Document

Signed in user tracking and privacy

It is possible to track the activity of a signed-in user, in association with their hashed user ID (HID). This means it is possible to associate activity across multiple sessions and devices to the same user account.

Note though that there are various measures in place to protect the privacy of users, while getting the best possible data.

Because of the differences between web and mobile, Echo manages this quite differently on each platform.

Table of contents

  1. Echo JS
    1. BBC Cookie preferences
    2. BBC ID
  2. Echo iOS/Android
    1. Enabling Webview Cookies
    2. Android
    3. iOS (Swift)
    4. Informing Echo About User State
    5. BBCUser
      1. Access and Identity Tokens
    6. Passing a BBCUser to Echo
    7. Token Expiration and User State Changes
      1. Disabling transmission when user state changes
      2. Android
      3. iOS (Swift)
    8. Local Storage
    9. Device ID
    10. Device ID reset
    11. User state change
    12. Echo device ID
    13. iOS device ID reset when using ad-hoc distribution (e.g. hockey app)

Echo JS

Browsers are identified using the atuserid cookie (domain=.bbc.co.uk). This cookie is set by the ATI library within Echo (or Reverb). If this cookie is deleted for any reason then a new cookie, with a new ID, is generated.

Alternatively this can be overridden using the idclient parameter of the request to ATI. This is set by Echo when a custom device ID has been provided. This is appropriate where you are working in an environment that does not use cookies, for example a desktop app or smart TV.

If neither of these identifiers are available/provided then ATI will infer the device from a combination of IP address and User Agent.

Users can opt out of performance cookies, but not cookies classed as “strictly necessary”, as explained here on the Cookie Settings page.

Analytics cookies are classed as strictly necessary, so there is no way to opt out of them.

In order to be anonymously tracked, a user can turn off personalisation on the Privacy and cookies page

If this option is toggled, their atuserid cookie will be reset, and if they are signed in they will be recorded as “unidentified-user” rather than using their hashed ID (see below).

BBC ID

When used in an Orbit page Echo will automatically detect if the user is logged in and has a hashed ID (HID) by using the idcta javascript module.

For a signed in user:

  • with a hashed ID (personalisation enabled): report the at value with the user’s hased ID
  • without a hashed ID: report the at value as unidentified-user

It is also possible, in a non-Orbit context only, to indicate that a user is logged in manually using the setLoggedInToBBCId() method:

  // Indicate user is logged to BBC iD with a hashed Id
  // sets bbc_identity=1 and bbc_hid=users-hashed-id
  echo.setLoggedInToBBCId("users-hashed-id");

  // Indicate user is logged to BBC iD without a hashed Id
  // sets bbc_identity=1
  // removes bbc_hid property
  echo.setLoggedInToBBCId();

  // Indicate user is logged out of BBC iD
  // removes bbc_identify and bbc_hid properties
  echo.setLoggedOutOfBBCId();
  

Echo iOS/Android

Clearly there are no cookies in a native environment (with the exception of webviews, see below), so device ID is always sent as the idclient parameter.

Echo iOS and Android support the IDv5 User Promise. The effects of this are described below. Note that this used to be optional but is not anymore. If you do not enable IDv5 then user tracking will be disabled.

As of versions 17.12.0 of Android and 5.8.0 of iOS, IDv5 is enabled by default and cannot be disabled. As such the instructions on enabling it are outdated and have been removed.

Enabling Webview Cookies

Webview Cookies are currently enabled by default in Echo iOS and Android. They also require IDv5 to be enabled.
For iOS the setting of Webview Cookies is only supported with a UIWebView. Other webviews such as WKWebView and SFWebView are not currently supported.

If your application uses webviews, then Echo will automatically take care of generating a device ID for you and ensure that the device ID is kept up-to-date according to user state changes. Echo stores the device ID in a cookie called ckns_echo_device_id on both ‘.bbc.co.uk’ and ‘.bbc.com’ domains.

Reverb (the analytics tracker that is present on Orb-enabled web pages) will pick up the ckns_echo_device_id cookie value and use it in preference to the value generated by ATI. This makes it possible to associate the web page views with the same device/session.

If your application is using the Auth Toolkit then you will need to update your cookie whitelist to prevent the `ckns_echo_device_id` cookie from being rejected.

To enable Webview Cookies on a given platform, follow the instructions below.

Android

Set EchoConfigKeys.WEBVIEW_COOKIES_ENABLED to true in the config HashMap passed to the Echo constructor.

iOS (Swift)

Set config[.webviewCookiesEnabled] to "true" in the config Dictionary passed to the Echo constructor.

Informing Echo About User State

Are you using the BBC Auth Toolkit? If your application supports authentication using BBC ID you should be using the Mobile Platforms Auth Toolkit.

The Auth Toolkit is able to automatically inform Echo about changes to user state and this is the expected pattern for integration. You should not need to create BBCUser objects within your application etc as the toolkit will take care of this. See Auth Tookit iOS and Auth Toolkit Android for more information.

The BBCUser object (see below) is used to:

  • encapsulate the state of a user (sign-in state, etc.)
  • provide an ID token refresh timestamp

When Echo detects a change in user state, e.g. signed in to signed out, a new device ID will be generated. During normal operation, where a user is likely to stay signed in or out indefinitely, Echo should not see any change to user state and should use a single device ID across multiple application sessions.

Applications using Echo are expected to:

  1. Inform Echo about the initial user state - Pass a BBCUser object to the EchoClient constructor that represents the last known user state. This will probably happen when your application starts up. The user state should represent the state of the user when the application was last used, even if the user’s ID token has expired.

  2. Inform Echo of any changes to user state - While your application is running a user may sign in, sign out or toggle personalisation. If this happens you must inform Echo by passing a new BBCUser object to the EchoClient.setBBCUser method.

  3. Inform Echo whenever the ID token has been refreshed - In order to remain authenticated it is necessary for an ID token to be refreshed periodically. Echo should be informed when the token is refreshed by creating a new BBCUser object with an appropriate value for the tokenRefreshTimestamp property and then passing the user to the EchoClient.setBBCUser method.

BBCUser

Both the iOS and Android versions of Echo can now be provided with a BBCUser object that represents the current state of a user. It is possible to create a user with the following states:

State Personalisation enabled
Logged out No
Logged in No (inferred from a null hashed ID)
Logged in Yes (inferred from a non-null hashed ID)

If no user is provided to Echo, by passing nil/null (or on iOS Swift, a new user with no arguments: BBCUser()) to the Echo constructor, the library defaults to a user object that is logged out with personalisation disabled.

When creating a user that’s logged in with personalisation enabled it is also necessary to provide a date object with the time that the user’s login token was last refreshed. Every time a user’s login token is refreshed, a new user should be created and passed to Echo with an updated token refresh timestamp. This will be used to determine when a user’s token has expired (24 hours after creation) and stop transmitting data until a new BBCUser object with a valid timestamp is provided (see the token expiration section section below).

Access and Identity Tokens

New in Echo starting from version 18.0.0 <= on Android and 5.8.0 <= on iOS, you can provide a user’s access token and identity token. See the examples below for details. These are JWT tokens, and set as string values in the BBCUser, if you are using Authtoolkit these will be provided to Echo from there.

If these tokens are not provided, they will be set to null/nil, and this may cause problems for certain reporting eg via BAG (for Appsflyer or UAS).

Passing a BBCUser to Echo

Providing a hashed ID

Please note that ATI will use the first hashed ID they receive, for the entire session. So updating a user as shown below will not be reflected in reports.

It is important to set the hashed ID of a signed in user at initialisation, or the ID of “unidentified-user” will be seen for the entire session.

If in doubt contact us!

Please ensure you have read “Are you using the BBC Auth Toolkit?” above.

  // Create user - all parameters except signedIn are optional
  let user = BBCUser(signedIn: true, hashedId: "hashed_id", accessToken: "access_token", identityToken: "identity_token", tokenRefreshTimestamp: Date())

  // Pass user into Echo constructor
  let echo = EchoClient(
      appName: "MyApp",
      appType: .mobileApp,
      startCounterName: "bbc.start.page",
      config: config,
      bbcUser: user
  )

  // Update user on Echo client
  echo.setBBCUser(user)

  // Example: not signed in
  user = BBCUser(signedIn: false)
  echo.setBBCUser(user)

  // Example: signed in without a BBC hashed ID (personalisation disabled, not old enough etc)
  user = BBCUser(signedIn: true, hashedID: nil, tokenRefreshTimestamp: Date())
  echo.setBBCUser(user)

  // Example: signed in with a BBC hashed ID and token strings
  user = BBCUser(signedIn: true, hashedId: "hashed_id", accessToken: "access_token", identityToken: "identity_token", tokenRefreshTimestamp: Date())
  echo.setBBCUser(user)
  
  // Create user
  BBCUser user = new BBCUser(true, "hashed_id", "access_token", "identity_token", new Date());

  // Pass user into Echo constructor
  EchoClient echo = new EchoClient(
    "MyApp",
    ApplicationType.MOBILE_APP,
    "bbc.start.page",
    getApplicationContext(),
    config,
    user,
    this
  );

  // Update user on Echo client
  echo.setBBCUser(user);

  // Example: not signed in
  user = new BBCUser(false, null, null, null, null);
  echo.setBBCUser(user);

  // Example: signed in without a BBC hashed ID (personalisation disabled, not old enough etc)
  user = new BBCUser(true, null, null, null, new Date());
  echo.setBBCUser(user);

  // Example: signed in with a BBC hashed ID and token strings
  user = new BBCUser(true, "hashed_id", "access_token", "identity_token", new Date());
  echo.setBBCUser(user);
  

Token Expiration and User State Changes

Based on the refresh timestamp provided (Echo considers the token to be valid for 24 hours), a user’s token will expire, and Echo will transition to an expired token state, unless a new valid token refresh timestamp has been provided before this time (in which case normal service will continue uninterrupted).

When a token is allowed to lapse (perhaps because of a network interruption or unavailability of the ID service), Echo will begin to cache all events and will not transmit them until the same BBCUser is provided with a new valid token refresh timestamp, at which point the cached data will be immediately transmitted and normal transmission will resume.

Disabling transmission when user state changes

For further user privacy protection, there is an option to disable transmission when a user’s state changes.

In the event that a BBCUser is provided with a different ID — or personalisation state is changed (whether in an expired token state or not) — Echo will disable transmission, the cached data will be discarded (to prevent it being associated with the wrong user), and transmission will not resume until the next cold start of the app. A user_state_change event will be sent with details of why this has happened, at the next available opportunity.

In this case, data will not be collected or transmitted during this time, or cached for future transmission. Data from this session will be lost. This is necessary to prevent persistent identifiers linking the two users’ activities and breaching the “user promise”.

To enable this feature:

Android

Set EchoConfigKeys.RESET_DATA_ON_USER_STATE_CHANGE to true in the config HashMap passed to the Echo constructor.

iOS (Swift)

Set config[.resetDataOnUserStateChange] to "true" in the config Dictionary passed to the Echo constructor.

Local Storage

To enable IDv5 functionality, Echo stores some data on the device’s local storage.

  • Android - Echo uses its own SharedPreferences store.
  • iOS - Echo uses NSUserDefaults. All keys used by the library are prefixed with Echo.

Here’s a description of what data Echo stores locally:

Key Example Value Description
EchoDeviceID 2fcc7a0e-89c6-47d7-b672-811e9a4f8064 The device ID that Echo uses for reporting
EchoHashedID f0ff23827982af083f1f160cfd0b791f The hashed ID of the last user provided to Echo
EchoDeviceIDCreationDate 1483971631859 A unix timestamp representing the time the user’s token was last refreshed
EchoSignedIn true Signed in state of the last user provided to Echo
EchoHardwareID 8af8770a27cfd184 Hardware identifier used by Echo (never transmitted)

Device ID

Echo uses an auto-generated device ID for reporting. Echo uses an RFC 4122 v4 compliant UUID as a device ID, e.g. 2fcc7a0e-89c6-47d7-b672-811e9a4f8064. The device ID is reported as idclient to ATI.

A new device ID is generated each time there is a change in the state of the user. The possible states are detailed in the table above.

Device ID reset

The device ID will be reset when a user without a hashed ID (ie under 13 or personalisation disabled) signs in, signs out or toggles EP.

Initial State New State Reset ID Example
Signed Out Signed in with HID No Register, VSI, MSI
Signed Out Signed in without HID Yes Sign in u13, sign in with EP=OFF
Signed In with HID Signed out Yes Sign out with EP=ON (this is to force a new ATI visit)
Signed In with HID Signed In without HID Yes Toggle EP to OFF
Signed In without HID Signed out Yes Sign out u13, Sign out with EP=OFF
Signed In without HID Signed In with HID Yes Toggle EP to ON

Echo will send one of two events to ATI in relation to user state changes and the generation of new device ID values:

User state change

This event is sent whenever there is a user state change. In some cases a new device ID will be generated.

Property Values
action_type user_state_change
action_name sign_in, sign_out, enable_personalisation, disable_personalisation

The device_id_reset property is only sent when a new device ID is generated.

Echo device ID

Sent when Echo generates a device ID due to a first install or Echo update (e.g. not due to a user state change).

Property Values
action_type echo_device_id
action_name first_install, echo_upgrade, hardware_id_changed, device_id_expired

The action_name=echo_upgrade event is only sent when an application upgrades from a pre-IDv5 version of Echo to an IDv5 version i.e. change from Echo with IDV5_ENABLED=false to Echo with IDV5_ENABLED=true. A general Echo upgrade where IDV5_ENABLED=true for both versions will not trigger the event.

The device_id_reset property is only sent when a new device ID is generated.

iOS device ID reset when using ad-hoc distribution (e.g. hockey app)

Echo uses the iOS identifier for vendor (IDFV) to determine if an app is being used on a new hardware device. A change to the IDFV value:

  • will result in a new device ID being generated
  • will result in Echo sending an event with: action_type=echo_device_id, action_name=hardware_id_changed, device_id_reset=1

Where an app update is installed using ad-hoc distribution Echo will receive a new value when reading the IDFV value, this will trigger a device ID reset. This includes installation using hockey app. This will not happen in production where an app update is installed using an app store distribution as the IDFV value will not change.