Countly tracks your users through an ID called the 'device ID'. This is attached to every request (which contain events and other data) that is sent to the Countly server. This ID consists of String characters.
This ID is normally (by default) generated in the environment the Countly SDK has been integrated into (e.g. a smartphone, a web browser, or a desktop application). But how you handle this ID would depend on how you define a user in your platform specifically.
What happens if there are several users and several devices that are used interchangeably? What happens if a user can log in and log out, hence transitioning between a known and an anonymous user? In such cases, you should experiment and decide on the correct user tracking strategy before going into production to minimize the negative effects. For an overview on how these different situations could be handled, look bellow.
Available Mechanisms For Interacting With Device ID
Countly SDK's try to be configurable and flexible, and handling device ID's is no exception.
Device ID During Init
Countly SDK's behave differently in the first on a device compared to subsequent init's.
On your first init, when integrating a Countly SDK, Countly will try to acquire a device ID. By default, Countly will generate a random value (for the device_id) to identify the user or use some platform-specific value; for example, IDFV for iOS, and then store it in the local storage.
On subsequent inits, the SDK would fetch and use this same value as the device ID and would not generate a new one. By default, the SDK would ignore any provided device ID values.
There are some configuration options during initialization. During the first init, it is possible to do the following actions:
- provide a custom device ID - SDK will use the provided ID and will not generate one
- tell the SDK which device ID generation method to use - in some SDK's it is possible to influence the ID generator and pick a specific method
- enable temporary device ID mode - while in this mode, the SDK will not send anything to the countly server until a device ID has been provided
- provide a device ID with a url parameter - this exists only in the web SDK. This provides a way to "inject" a device ID on a first run.
Some SDK's might have a "clear stored device ID" flag that can be set during init. If this is done then the SDK will clear it's stored value and will try to reacquire a device ID value and would behave like on the first init. It is generally not advised to use this flag as it can cause user count inflation issues.
For a deeper overview in how the SDK would behave in different situations, have a look at this table.
Changing Device ID
Countly SDK's provide two ways to change the device_id after the SDK initialization:
1. Change device_id without merging. That will simply end the session of the old device_id, sync all the left data, and start a new session for the new device_id.
This is handy, for example, when multiple users use the same device and you want to track them without sharing their data individually.
2. Change device_id with merging. This will create a new user with a new device_id, and start a new session. Then, merge the data of the anonymous user with the old device_id into this new ID. And afterward, delete the anonymous user with the old device_id from Countly and only keep this user's information under the new, developer given ID.
This is handy when, for example, you are firstly tracking an anonymous user with a Countly generated device_id, but then the user authenticates so you retrieve the ID for this user and change it in the SDK, allowing to merge both users on the server. This means that everything that the anonymous user had, all events and properties, will now be assigned to an identified user and the old user will be deleted.
You can implement different strategies that utilize these two options with the help of device ID type information. Most Countly SDKs provide calls to see the current device ID and the device ID type. The main types you would like to check for device ID management are to see if the ID was SDK generated or developer supplied.
Offline / Temporary ID mode
It is possible to launch the Countly SDK in an offline/temporary ID mode during the first initialization. This mode can also enabled after initialization with the use of special calls exposed by the SDK.
If this mode is enabled, no data will be sent to the server until a real device ID value is provided by the host app. After that is done, all stored requests will be marked as create by this device ID and then sent to the server and assigned to this user.
Device ID Type
Most Countly SDKs provide calls to see the current device ID and the device ID type. The main types you would like to check for device ID management are to see if the ID was SDK generated or developer supplied.
Different user tracking strategies
Default User Tracking
Like mentioned in the "Device ID during init" section. With no additional configuration, the SDK will generate a random device ID on the first init and then use it.
Generally speaking, this way assigns a unique ID to a particular user who is the owner of that device (phone, browser, PC, or tablet)
- This is the easiest and fastest implementation, with no additional steps needed other than undertaking the default SDK implementation.
- If multiple different users use the same device, they will be identified as a single user in the Countly dashboard and will have a single profile under User Profiles.
- If the same user uses multiple devices, each device will be identified as a separate user in the Countly dashboard; hence the same user will have separate user profiles.
- Depending on the platform, if app storage is reset (erased) or the app is uninstalled and re-installed again, this user most likely will be identified as a new user and a new user profile is created. This highly depends on how the platform behaves. Check here to understand what happens in such cases.
Tracking Known Users
This method, as opposed to the first one, helps Countly identify and track users if they are known to you. It is used when tracking the same user across multiple devices or different users on the same device, as the default tracking method is not appropriate. In this case, you need to provide your user identifier as the device ID. This unique identifier can be a user email address or an internal customer ID — or simply anything unique to that user. The Countly SDK can then use this string as the device_id. From this point on, Countly will know precisely what user it is and the same device_id will be used even across different devices.
To accomplish that, you need to provide a string value as the device_id upon the SDK initialization inside the config object. The user authentication page is a good candidate for implementing this method. So this might fit applications that can identify their users right away during the SDK init, or have little or no actions before authenticating users.
This would be the case when the user inside the Countly dashboard directly corresponds to your customer (e.g. 1 Countly user = 1 company customer, regardless of the device or platform they use).
- Each of your customers will be exactly 1 single user inside Countly and have 1 user profile.
- If you do not know your user ID right away and would know it only after the user authenticates, you would miss all the actions that were made before authentication.
Known User With Pre-Tracking
To tackle the problem of missing out on data before user authentication, it is possible to launch the Countly SDK in an offline/temporary ID mode. This mode is described in the Offline / Temporary ID mode section.
This way, you can track everything needed before knowing the users identity. When the user finally authenticates, and you get your user’s identifier, and use that to exit the Offline / Temporary ID mode
For the definition of the user, nothing changes - it still directly corresponds to your customer.
- Each of your customers will be exactly 1 single user inside Countly and have 1 user profile.
- You will have the opportunity to be able to collect and visualize data before the user authenticates, but only after authentication.
- If your user does not authenticate (and so be known), you will never receive any data from this user.
Managing Anonymous and Known Users Together
It is also possible to collect data of both user states (before login/known and after login/known) and manage the ID using the functionality discussed in the above changing device ID section.
You can implement different strategies that utilize these two options with the help of device ID type information discussed device ID type section.
So with this knowledge, for example, you can start tracking a user as anonymous with a Countly generated ID. Then, upon authentication, change the device_id to your own ID by merging. And then, when the user logs out, you can change it back to the anonymous generated ID without user merge. The problem is that when the user logs out, it will create a new user inside the Countly dashboard again, and there will be 2 different user profiles: one with your provided ID and the other with a random ID.
So the user on the Countly dashboard represents both your customer and anonymous user before authentication. And in some cases, it could be the same user but with 2 different user profiles inside Countly. For applications like banking, where the user must log in and log out every time, that can double the user count, thus skewing the data.
You can try to tweak this strategy to minimize double-user creation. For example, upon logout, let’s not change the device_id at all and keep using your provided one. Instead, upon authentication, we check if the type of device_id provided is yours, if it is we switch the device_id without merging. But if the type of device_id is Countly generated, then we change the device_id with user merging.
In such a case, the scenario would look like this:
- The app starts for the first time and a Countly-generated ID is created.
- Upon authentication, you confirm that the current device_id is Countly generated; it means we need to do merging when switching to your provided device_id.
- When the user logs out, we do not do anything.
- When the user logs in, we check the current device_id and we see that it was provided by you. So we switch to the authenticated user’s device_id without merging. If it is the same user and the same ID the SDK currently has, nothing will happen. But if it is a different ID, then it is probable that another user logged in and the SDK will stop the current session and start a new one for the new user.
These are just a couple of examples of how you could manage tracking data for both known users and anonymous ones. The actual implementations may differ based on your application specifics. But an example integration of the mentioned method can be reached from here
- You get to track data for users both before and after authentication.
- In some cases, aggregated data may be skewed and may over-report users and new users due to many anonymous users getting created.
- Merging can be quite a performance-intensive process, especially if the user that is merged has a lot of data or there are lots of users to merge.
- In some cases, the same user may have a user profile for both states: a known user and an anonymous one.
- It requires SDK integration and customization which is slightly more difficult.
Other Known Strategies
We have seen our customers using their own different implementations, and one of them was quite effective, which is why we have included it here. This strategy involves dividing the onboarding (pre-authenticated users) and authenticated users into separate Countly apps.
In this scenario, the customer had quite a long and complicated onboarding process with the registration form. But once that was done, there was nothing else to do before the login screen. So they wanted to utilize 1 user profile per 1 customer inside the Countly dashboard. But they also wanted to track how a user onboards, how long it takes, and where they would drop off if registration was not finished.
That is why sending onboarding data to one app and then sending data of known users to the other app made perfect sense for them.
Another strategy could be you also leaving a custom property with your user ID once registration is complete on the onboarding app, just to be able to tie both users together. But note, this approach would require changing app_key in the running SDK, and currently not all SDKs support that. You would need to consult Countly or make modifications yourself on certain SDKs.
There are different user tracking strategies available. Each one has its own pros and cons. You need to understand what kind of data you want to collect and what you want the word user to mean exactly for you in the Countly dashboard. Make sure you know the options and then you would be able to find the best way that fits you with all its trade-offs.