To begin with, you have to differentiate and define opt-out users and app uninstalls:
Opt-out users are users who disabled notifications.
App uninstalls refer to users who uninstalled the app.
You can track your opt-out users in the Analytics → Reach tab.
Batch can only have information about what's going on in the app. When a user installs and opens the app, we receive a push token from Apple/Google that allows us to communicate with them.
If the user opt-outs from notifications in the device settings, no information is provided to Batch servers. The actual opt-in status will be updated only when the user opens the app again, or when a push is sent to this token (thanks to Apple's or Google's feedback). Likewise, we do not know in real-time when an opt-out user activates push notifications again.
Therefore the Batch database is potentially always "out of synchronization" with reality regarding the opt-in status.
Batch always targets all opt-in and opt-out tokens: it allows us to update the state of the tokens, clean the database and recover the users who would have reactivated the notifications. The notification will never be displayed to an actual opt-out user, it will be blocked by the device.
Note on Android
On Android, users are opt-in to push notifications by default. The number of opt-out users corresponds to the users who have willingly disabled notifications from the app preferences.
The Batch SDK cannot simply detect an opt-out from the device settings because, unlike iOS, an app can offer opt-in categories called "channels". For Batch, a device will be considered opt-in to push notifications if the global notifications toggle is enabled and the default notifications channel is enabled in the settings of this app.
There are two pages where you can track your app uninstalls:
In this example, we report that 80 users, who were known as opt-in, did not receive the push because they uninstalled the application.
Unlike opt-outs, we receive by return loop the uninstalls that took place between the sending of the last campaign and the campaign of the day. This loop occurs only once a campaign has been sent. That's why you will see uninstalls only on days where a push has effectively been sent.
Note: Sending a test push notification won't trigger the uninstalls detection.