FAQ

Why do some events occur in the stream multiple times?

While we take measures to prevent them, duplicates could appear in the stream for a number of reasons. If your use case can’t tolerate this, we provide an ID on every event that can be used to de-duplicate. Users of the PARTITION subset should note that partitioning is done by ID, so duplicates will always be on the same partition of the stream.

Why do events appear in the stream with occurred_at from the fairly distant past?

Devices which are unable to send events to Urban Airship due to lack of network connectivity will save events generated and dispatch them the next time the app is open and the device is connected to the internet. This can lead to events not reaching the Urban Airship systems until long after they happen. We don’t process or pass through any events older than 90 days, but if you require stricter latency requirements look into the latency filter.

Why do events appear in my stream with occurred_at in the future, or with occurred_at after processed_at?

Because device clocks are frequently unreliable, at times we receive events that the device claimed occurred in the future. If an event claims to be from more than 5 minutes in the future, we don’t trust the device clock and instead mark the event as having happened at the current time according to the server.

Why do events come in with out of order occurred_at times?

Events may be out of time order for the app in general, but also for a single device. This is due to the on-device latency mentioned above, but also because events are processed in parallel. Consequently, no guarantees are made about the order that events appear in the stream.

Why do events come in with out of order processed_at times?

As mentioned above, the systems which process events and prepare them for consumption via the Connect API run in parallel, and so cannot guarantee the events in the resulting stream will be ordered.

Why do some events seem to be missing? e.g., “I see an OPEN but no CLOSE.”

This can happen for several reasons:

  • Events are batched on the device, but in order to limit the impact on device storage they may be dropped if the device has been unable to communicate with Urban Airship’s servers and has hit the internal storage limits.

  • Events may arrive in different batches, with significant gaps in between send times. While the Urban Airship SDK will attempt to flush all buffered events on app close, it may not be able to do so. This could mean that the second event will not be received until the next time the app is opened with network connectivity.

When a push goes to an uninstalled app instance, why do we get both a SEND and an UNINSTALL on iOS but only an UNINSTALL on Android?

Because GCM (Google’s notification transport system) sends feedback on uninstalled devices synchronously in their API response, whereas APNs (Apple Push Notification Service) sends them later via a separate channel, we can immediately discover that an Android user has uninstalled and not mark them as being sent to. We cannot do this for an iOS user. Because this is platform-dependent behavior, it is subject to change.

Why did my stream contain a PUSH_BODY for a push that went to 0 devices?

PUSH_BODY events are generated at the time a request is made to our push systems, either via the composer or push API. We do not yet have the information at that stage to determine if anyone will be sent to for the specified audience.

Why does my stream contain a SEND event for a device, but that device never received anything?

We emit a SEND event when the push platform (APNs or GCM) informs us that it has accepted the push request. That push platform might then fail or otherwise be unable to send the push to the specified device, but we will not receive feedback on this unless the reason that the device is unreachable is that the app has been uninstalled.

Why do I get TLS handshake errors when I try to send a request to the Connect API?

In order to protect your data, we support only the newest TLS version (1.2) with a modern cipher (TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 or TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). Some older HTTP libraries may not support this, but we have confirmed that the following work:

  • Java 1.6 or newer, but will require the JCE Unlimited Strength package appropriate for your java version from Oracle

  • Python 2.7.9 or newer

  • Python 3.4 or newer

  • Golang 1.5 or newer

  • NodeJS 0.10.33 or newer

  • Any HTTP library linked against OpenSSL 1.0.1f or newer. OpenSSL 1.0.1e-fips which ships with Centos 6 also supports the needed ciphers

Why do I get an HTTP 402 error code when I try to issue a request to the Connect API?

The number of simultaneous connections for a given connection point is restricted, and any connection attempt which would exceed that limit will receive an HTTP 402 error response. If this continues to occur after retrying for at least 30 seconds, please contact support.