With Omniata, it's possible to instrument analytics in your mobile application either through your server or through the client with a SDK (the device running the application).
Both have advantages and disadvantages that should be considered before launching your application.
Client Integration via SDK
When integration your application to send Events to Omniata, you need to decide whether to send the Events from your end users' devices, from your server (given you have one) and when sending from the devices, whether to use Omniata SDKs or not.
The short version is that Omniata provides SDKs for several platform (iOS, Android…) to send the events from the client. These SDKs take care of lot of aspects related to the event sending. Thus it’s recommended to use SDKs and send the events from the clients.
The rest of this answer describes to various aspects related to Event sending when not using one of Omniata SDKs.
When sending events without Omniata SDKs at least the following are aspects to take into account - applies both sending from the devices and from the server:
The events of a single user have to be sent to Omniata in the same order they were generated by the end user, e.g. if you send a level_up events (to track the level a player is in your game) and om_revenue events (to track revenue) in your application to track revenue per level, and level_up and om_revenue events are sent in wrong order, the revenue gets reported on a wrong level.
Currently Omniata has one second precision for the Event timestamps and sorts events by Event timestamp. This means in practice that if you send multiple events within a second, Omniata receives them in the correct order, but is not guaranteed process them in the correct order. This is because the events have the same timestamp and there's no other field in the event that Omniata could use to order the Events. Omniata SDKs have a workaround for the issue - they wait at least one second between each Event sending. This way each event (of a user) has a different timestamp and ordering by timestamp works. If you send multiple events (for the same user) within one second, you need to do something similar to ensure the correct ordering in Omniata.
Omniata supports various parameters in om_load that all the SDKs add automatically, see the SDK descriptions. If you want to leverage the functionality provided by these parameters, you need to implement those parameters yourself in your code. In the case of sending from the server, essentially you need to pass the values from your client to your server and from there to Omniata. See SDK documentation for the list of the parameters and specific SDKs (iOS, Android etc) on how to dig the parameters on each platform. Note some SDKs add additional non-common parameters (like the bundle version in iOS), see the SDK documentation for details.
Omniata SDKs add om_delta parameter to each event, it's recommended you add the parameter yourself when sending events from the server side, see SDK documentation for details.
Especially with mobile devices it’s really important to handle cases when there’s no network or if event sending fails because of network problems. It's recommended that you buffer the events on the device and retry sending if it fails. Also, it's important to check in the sending code whether networking is en abled and not send the events when the network is disabled.
When sending events from the server:
See the list above for the common issues, additionally:
Country detection works in Omniata using the TCP client IP address in the Event API. When sending from a server, this approach will recognize the country of the server, not the original user. There workaround is to use x-forwarded-for header. Search elsewhere in the documentation for the details of the country code detection.
If your application is not always connected to your server, your events will be sent to Omniata earliest when the application next time connects to your server. This will cause the events to be timestamped in Omniata on the time when they were received by Omniata, which differs from the actual event creation time.
Omniata calculates session counts and lengths based on the event receiving timestamps, search elsewhere in the documentation for the exact logic. If your servers maintains events and sends them later to Omniata (not with similar time difference between the events as they were created on the device), this will cause the session count logic not to be accurate.
To recap - the events of a single user need to be sent to Omniata in the same order they were created.
One approach to send events in FIFO order (per user)
When sending events from the client (but not using Omniata SDK):
Pay a lot of attention to retry mechanism - do not underestimate the importance. Based on Omniata's experience, it's known that if there's no retry mechanism, a significant event loss (events seem to be sent from the client, but are never received in Omniata) will occur. When implementing your integration, test carefully different error and race conditions such as network unavailable. When your application is live, there's not necessary any way for you to find out whether the event sending works. It's recommended that you implement some kind of secondary mechanism of tracking Event sending failures, e.g. send an Event to Google Analytics when Event sending fails.
A user of an application that is integrated with Omniata needs to be identified by a user id. The main requirement of a user id is that it's unique within the project and uid domain. Omniata is not interested in how user ids are created and assigned.
The meaning of user id and how to get and create it greatly depends on the platform (mobile, Facebook, web etc). In Platforms where the concept of user id exists natively (Facebook etc) that native user id can be used as Omniata user id as such, since it fulfills the uniqueness requirement.
In platforms where the concept of user id doesn't exist natively (iOS, Android etc), different approach needs to be taken and the application integrating with Omniata needs to create and maintain the user ids. One approach (e.g. on mobile devices) is that the application creates a user id locally in the application when a user installs the application and when the application is uninstalled, that user id is forever lost. In this approach, if a user re-installs the application, he gets counted as a different user. A variation of the same approach is that the application gets the user id after installation from the application's server side and the server side uses whatever mechanism to create the user id (SQL sequence, MongoDB ObjectId etc).
A few examples on how to actually create a user id on a mobile device:
iOS: you can use NSUUID Class UUID method to create a user id
Android: java.util.UUID can be used
All event types, user IDs, event parameters and event values are case sensitive in Omniata. The case is preserved through the API call. It is important to make sure your use of cases is consistent through your entire integration.
Omniata recommends that all events, event types, parameters, and values are sent in lowercase to avoid confusion for capitalization rules. For user IDs, it is important to pass the ID as intended:
Android ID 38400000-8cf0-11bd-b23e-10b96e40000d
A new event type will be created for each variation.
A user will be counted for as many variations of the id. For example, a user will be counted twice if uppercase and lowercase spellings are sent. This will result in inflated DAU and New User counts, as well as skewed retention.
Event Parameters and Values
Event Fields by default will be created for each variation. This can be solved by including all of the variations in the parameter option, or by including the variations in the LUA ('Level' or 'level' or '0')
The values will be returned case sensitive as well, which can result in lower counts than expected per variation.
Using a different case than the one provided in the lookup table will result in an '[unknown]' string being returned for a string value, or a 0 for a number.
Once new parameters are being included in the sent events, you'll need to run the Event Scanner to find those new parameters. Once you've initiated an Event Scan, it will search for all the parameters sent on all events within the time period, and upon completion there will be the option to add the new Fields to the Data Model.
Omniata highly recommends verifying om_revenue events before being sent to Omniata.
Apple iOS Receipt Validation
Google Android Purchase Status API
We don't currently block excessive traffic from a single IP address, or a small set of IP addresses. Remember though, when sending the Events from the server side there are certain issues you need to take care of, such as setting the original IP address of the end user. Please check more information in the section on Application Integration.
A good approach is to engineer your application so that when you make the Channel API request, there's a max socket timeout that you're willing to wait, e.g. 5 seconds. If you don't get answer in that time, forget it.
You could setup your application so that when it initially starts - 1st time ever for a single user, it requests content from the Channel API and that request assigns the user in an Experience of an Experiment. If that request fails (timeouts or non 200 OK response), you can consider the user not to belong to any experiment. This way your application is always accessible even if Channel API had issues. You could then mark on your applications side that this user is not part of an Experiment at all.
However, the Channel API is not fully atomic. Especially if you cut the socket, it's possible that the Channel API will mark the user to belong to an Experience of an Experiment. In this case your app and Omniata will go out of sync. This is a rare case that doesn't affect the results significantly.
The om_load event sets certain variables in the User State, such as the country. If that event fails and that's the only event for that user and you make a Channel API request, the Channel API request will work well (serve content, mark the user to an Experiment), but the Channel API doesn't know anything about the user (such as the country), so the targeting on User State doesn't work as it should.
Note that independent from whether the initial om_load has been sent or not, a single user always gets assigned to the same Experience within an Experiment. This is because the Experience picked depends only on the user id, and is not function of anything else.
Prior approval is required before scheduling or implementing load tests. Omniata requires that our clients inform us of the parameters of the test, including the total number of events expected to be sent and what APIs will be tested (Event API, Channel API or both). In addition, the exact time period (beginning and end) that the test is expected to run needs to be given, allowing Omniata to coordinate with any other tests that could be running in parallel. An endpoint will be provided that allows Omniata to monitor the test and shut down if necessary, for example if the test exceeds approved parameters.
Please contact your Account Manager for any questions or additional details regarding this task.