Developer can himself decide how to identify users of applications in devtodev. There are 2 variants available:
Identification by unique device id.
Identification by user id set by developer.
And for both variants, just after getting the data in devtodev for the first time, there will be unique devtodev id (for user or device) created.
If developer does not set (or hasn't set yet) user id during SDK integration, then devtodev automatically uses device identifier:
Registration of new user is the appearance of identifier which did not exist in database when the first dataset came from SDK.
First dataset is sent just after SDK initialization it the code of application.
If the advertisind ID is changed, switched on or off, SDK notifies server about id replacement. So, the change of id does not create new users.
This method is useful, if it is nessesary to calculate devices where the app is launced, but not users who do it. Or it is useful when the numbers of devices and users are taken to be equal.
Usually this type of identification is enough for mobile devices, if the application can't save user data on server to expand it to this device, another device or another platform (for cross-platform projects).
It is not recommended to use this method for web applications, but it is possible to temporary use it if the user does not identify (for example, if there is a demo access to the app before the registration).
Every string corresponds with SDK initialization in the app.
User has launched the app on device A. There takes place a registration of new user in the app by device id, the user assigns devtodev id=1.
User has launched the app on device B. There takes place a registration of new user in the app by device id, the user assigns devtodev id=2.
User has launched the app on device C. There takes place a registration of new user in the app by device id, the user assigns devtodev id=3.
User has launched the app again, and the user was found by device C id. The user is still identified under id=3.
User has launched the app again, and the user was found by device A id. The user is still identified under id=1.
If the developer knows the unique user id, he/she can identify users with this ids, aside from devices where this id works.
This type of identification is not used by default, it works only if the developer sets the user id during SDK integration (setUserId method).
This method is universal. The main reason of not using this method can be absence of unique user identifier.
This method is strongly recommended for apps where there is possible to save user data on server to use it then on the same or another device, and also for applications where different users can use the same device.
This method is obligatory for cross-platform projects, because user can use the devices of different platforms to change the data about himself/herself (for example, the progress into the game), and you want to use devtodev cross-platform analytics and analyze the whole project in block.
Web SDK can use 2 user identifiers at the same time. First one is set during SDK initialization, and it can be the only id (for example, id of user in social network), and the second one is set only for cross-platform projects. If it is the same value for your project, set id only during the initialization.
If the user id was not used earlier in the app and it is integrated in the new version of application (or user had no id for some time, and now it appears), then all the data got by device id is inherited by first set user id.
In this case identification by device id is replaced with identification by user id. Data about number of users is not changed, because registration dates are also inherited.
User launches the app on device A. There takes place a registration of new user in the app by device id, the user assigns devtodev id=1.
User launches the app again and was found by device id. The user is still in database by devtodev id=1.
There was the assignment of user id in setUserId method. All the data previously got from device A are now under "John" id. Device ID A is replaced by "John" in devtodev database. The user is still in database by devtodev id=1.
The next launch of the app, and user id is not set by setUserId. SDK thinks that user id should be the same as in previous session. The user is still "John" under devtodev id=1.
There's assignment setUserID="John" in this or next sesson. Devtodev id is not changed.
User "John" launched the app again, he was found by user id. The user is still under devtodev id=1.
User id "Jim" is set on the same device in this or next session. There were no data about such user in devtodev before. There takes place a registration of new user, and now he's under devtodev id=4.
The next launch. User ID is not set with setUserId. SDK thinks that user id is the same as in previous session. The user is "Jim", and he's under devtodev id=4.
User id "John" is set on the same device in this or next session. This user is already registered in devtodev, and he's under devtodev id=1.
The next launch. User ID is not set with setUserId. SDK thinks that user id is the same as in previous session. The user is "John", and he's under devtodev id=1.
User id "Alex" is set on the same device in this or next session. There were no data about such user in devtodev before. There takes place a registration of new user, and now he's under devtodev id=5.
User "John" launches the app, he was found by user id. The user is still in database by devtodev id=1.
There is a launch of the app on device B under user id "John" set by setUserId method. The user is already registered in devtodev, and he's still in database by devtodev id=1.
There is a launch of the app on device B, but user id is not set by setUserID. SDK thinks that user id is the same as in previous session. The user is "John", and he's under id=1.
There is a launch of the app on device B under user id "Alexia" set by setUserId method. There is no data about such user in devtodev database. There's a registration of new user, and she assigns id=6.
There's a launch of the app on device D under user id "Alexa" set by setUserId method. The user is already registered in devtodev, and he's still in database under devtodev id = 6.
User "John" launches the app again, he was found by user id. The user is in database under id=1.
User launches the app by demo access, user has not permanent id. setUserId ="" is set during initializtion. Since there's no user id, SDK will take this user into account by device id. Only John used this device before, there is no id of device A in devtodev database. The registration of new user takes place, the user is in database under id=7.
The next launch is from device A, user id is not set using setUserId. SDK thinks that user id is the same as in previous session. There was setUserId ="" on the previous session, so the users was took into account by device id. The user still takes into account as devtodev Id 7.
User "John" launches the app again, he was found by user id. He's in database under id=1.
There's an assignment setUserID="Jane" on this or next session. User "Jane" did not use device A before, so it is assumed that Jane is user who previously used demo access, then registered and got the user id. Jane inherits all the data previously got by device id. Jane has not previously registered in devtodev, so she inherits devtodev id=7.
There is new launch of app in demo access, and again user has not permanent id. setUserId ="" is set during initializtion. Since there's no user id, SDK will take this user into account by device id. Until this moment the device was used by Jane, she inherited id of device A and then replaced it by "Jane" in devtodev database. The registration of new user takes place, because there is no such id in devtodev database. The user is under devtodev id=8.
There's an assignment setUserID="George" on this or next session. User "George" did not use device A before, so it is assumed that George is user who previously used demo access, then registered and got the user id. George inherits all the data previously got by device id. George has not previously registered in devtodev, so he inherits devtodev id=8.
It could be any available identifier of user (but not device). Examples:
user id in developer server database
user id in social network
market game center id, publisher id
telephone number etc.
Moreover, if your project is cross-platform, use the id which available from all of the platforms.
We recommend you to assign the user id before the SDK initialization. It is the most sustainable way to avoid data distortion.
In most of the cases, if you assign user id after SDK initialization, nothing is broken. But if several users use the app, or the project is cross-platform, then the data distortion is possible. SDK "thinks" by default that the same user launches the app next time. You have to use another user id to avoid it.
Let's have a look at the examples:
User "John" launched the app and then close it. Then user "Jim" opened the app from the same device, but SDK did not know about it, so it thought is was John again. All events (before initialization of "Jim") belong to "John", so DAU, users online metrics, date of last John's visit, John's events and user profiles are become distorted.
User "John" plays cross-platform game on his android pad. At friend's home, John installs the app on friend's iPad. Since the SDK initialization is before the moment of user id assignment, SDK takes device id into account. The new user is created on devtodev server with device (iPad) id. Then there's an assignment of "John" identifier, but server already knows such user and doesn't think that it is the user who inherited all the data from iPad device id before. So, the number of users, DAU and users online are distorted.
When the app works, it is possible to change user an unlimited number of times (for example, to relogin the user). You just have to make an assignment using setUserId. In case of web SDK, if id using during initialization changes, you have to repeatedly initialize SDK with new id.
When changing the user, we recommend you to also assign the current user level to the user (if you have such parameter).
If the developer needs to change the user id (for example, if developer wants to use another variant of identification), it is needed to use replaceUserId method once, otherwise users with new ids will be taken into account as new users.
Also developer shall do the same if it is possible for users to replace their id themselves (for example, to change their email which is used as login).
Platform
Main identifier
Additional identifier (if main identifier is not available)
Android
Advertising ID
id generated by SDK it changes after device data cleaning and after deleting the app)
iOS
IDFA
IDFV
Mac
ID generated by SDK using Hardware UUID (can not be changed)
Windows Phone 8.1, Windows 10
Advertising ID
Identificaton using App Specific Hardware ID can not be changed)
Windows (Standalone apps)
identifier generated by SDK it creates once, then saves on the device)
Web
identifier generated by SDK it creates once, then saves in localstorage or browser cookies)
#
Device
User id
devtodev Id
1
A
null
1
2
B
null
2
3
C
null
3
4
C
null
3
5
A
null
1
#
Device
User id
devtodev Id
1
A
not set
1
2
A
not set
1
3
A
"John"
1
4
A
not set
1
5
A
"John"
1
#
Device
User id
devtodev Id
1
A
"John"
1
2
A
"Jim"
4
3
A
not set
4
4
A
"John"
1
5
A
not set
1
6
A
"Alex"
5
#
Device
User ID
devtodev Id
1
A
"John"
1
2
B
"John"
1
3
B
not set
1
4
B
"Alexia"
6
5
D
"Alexia"
6
#
Device
User id
devtodev Id
1
A
"John"
1
2
A
""
7
3
A
not set
7
4
A
"John"
1
5
A
"Jane"
7
6
A
""
8
7
A
"George"
8
devtodev data does not always match the data from app stores or other systems therefore the metric values may differ. There are several reasons for that and here are some of them:
App installs
There is a significant difference between installing an app and actually opening it, but these two metrics are often confused. An install is a downloading of the app and installing it while the opening is the first launch of the app on your device. To analyze the number of installs in devtodev, you can use the Market Downloads metric.
Second, the devtodev SDK only starts when the app is first opened (essentially, it needs to be activated by the user). Once the SDK is fired for the first time, it sends a signal to our servers, letting us know that a new install has occurred. So we get to know about an app install on a new device only when the SDK reports about it.
This can also influence the time of installation because devtodev considers it to be the first launch but Google and Apple - the time of download.
In devtodev, the number of new users does not equal the number of downloads from the stores. Make sure that you compare the number of installs with the number of installs but not the number of openings with the number of installs.
2. Installs based on user and gadget data
App stores calculate installs by drawing information from user accounts and gadgets. In the Play Console, for example, Installs by user are the number of unique users who installed the app for the first time (based on store user accounts). In the App Store, it is the total number of times your app has been installed on devices with iOS 8 or tvOS 9, or later. Redownloads on the same device, downloads to multiple devices, sharing the same Apple ID, and Family Sharing installations are included. devtodev calculates installs based on a unique gadget ID. As a result, if some of the users change their unique IDs, the user count in devtodev may be more than in other systems.
3. User geolocation
App stores base their data on the geolocation of the store’s account while devtodev identifies the IP address. Let’s say there is a user with a Russian account but he is currently located in the US. The stores will consider all installs from the account as they were made in Russia, but devtodev will write them as American on the user card. Therefore, there are some differences between the two platforms in terms of install time and user geolocation.
4. User time zone
Platforms may differ in how they handle time zones. It is better to agree on some universal standard to avoid data discrepancy. In devtodev you can change the time zone using the Space settings:
5. Installs from third-party sources
If your app (an APK file with integrated devtodev SDK) is available not only on the stores but also from third-party sources like forums etc., devtodev will take these installs into consideration, while the stores will not.
6. Motivated traffic: ad ID reset
If you run campaigns using motivated traffic, some of your users may engage in fraud to be rewarded. They often reset their ad IDs and reinstall the app. After they receive a new ID, devtodev considers them as new installs. The stores ignore the duplicate installs.
7. Fraudulent in-app purchases
In case you compare income data from the stores and devtodev and find out that they don't match, you can try using a devtodev’s anti-cheat method that validates all transactions and only the validated ones get passed to the analytics system.
A problem may occur if the app gets hacked and users start making in-app purchases for free. Purchase queries of this kind are not passed to the Google Play or Apple Store.
8. App update
Some users install the app without the devtodev SDK and that may cause the discrepancy. After they update the app, they will be added to our system as new users. The stores see it as a routine app update because the app was installed before the integration with devtodev. While in the devtodev statistics, you may see a spike immediately after the update, but later it will improve and the data will become more accurate.
Is it possible to export raw data? Yes, devtodev allows you to export raw data in a form of a CSV file.
For how long do you store raw data? Raw data in devtodev is stored for 90 days, this includes TutorialStep, LevelUp, Progression, InAppPurchase, and Custom events. The Payment event and some basic metrics are available in the system without time limits. In case you’d like to extend the period of raw data storage, please contact our support team to discuss possible options.