At a glance: AppsFlyer uses silent push notifications once a day to verify apps are still installed on user devices, and counts uninstall events that occur for a specific app, attributing them to a specific media source. AppsFlyer supplies the raw uninstall data via a downloadable report, Pull API and Data Locker.
Benefits of uninstall measurement
- Compare media sources quality
The rate of uninstalls is a metric, which can help compare the quality of the users you acquire from different media sources, campaigns, single ads or countries. - Protect users privacy
Many advertisers run re-engagement campaigns to retain their users. However, doing so may contradict the app store's terms of use. If this is the case use the uninstall data to remove uninstallers from retargeted audiences.
Operating systems
Supporting the Uninstall Measurement feature requires some development in your apps.
Here are the developer instructions for:
Tip
How many users uninstall apps and when?
Get the full category/country breakdown here.
Important
Starting May 29, 2019, Google removed the GCM server and client APIs. If you are integrating messaging in a new app, use FCM. If you use GCM, upgrade to FCM. After you upgrade to FCM follow the instructions in this article to set up uninstall measurement for Android.
Follow Google's documentation to learn more:
Android uninstall measurement
Uninstall measurement using Firebase Messaging is supported as of Android SDK version 4.7.0.
1. Obtaining the Firebase server key
- Create a Firebase Android Application project (if you have not already done so), or migrate your project from Google Developer Console (follow the instructions there). For more information, go to Firebase.
- Open the Firebase Console.
- In the Firebase Console, navigate to the Project Settings (click on the cogwheel next to Project Overview on the left pane of the page).
- In the Cloud Messaging tab, you can see the two Server Keys (see screenshot below):
- Copy the Server Key.
2. Entering the server key on AppsFlyer dashboard
- Go to your app's dashboard on the AppsFlyer platform.
- Select App Settings from the left menu.
- Set the Firebase Server Key with the Server Key you just copied.
3. Configuring Firebase-messaging on your app
- Download google-services.json from Firebase console.
- Add the google-services.json to your app's module directory,
- Add rules to your root-level build.gradle file, to include the google-services plugin:
buildscript { // ... dependencies { // ... classpath 'com.google.gms:google-services:4.2.0' // google-services plugin } }
- Add the FCM dependency to your app-level build.gradle file:
dependencies { implementation 'com.google.firebase:firebase-messaging:17.3.4' } // ADD THIS AT THE BOTTOM apply plugin: 'com.google.gms.google-services
The latest Firebase version can be found here: Firebase official doc.
If you receive a "Could not find.." error, make sure you have the latest Google Repository in the Android SDK Manager.
4. Implementing AppsFlyer uninstall measurement service
If a developer integrates FCM for the sole purpose of measurement uninstalls with AppsFlyer, they can make use of the appsFlyer.FirebaseMessagingServiceListener service, included in our SDK.
This is done by adding the service to the AndroidManifest.xml:
<application
<!-- ... -->
<service
android:name="com.appsflyer.FirebaseMessagingServiceListener">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<!-- ... -->
</application>
The appsflyer.FirebaseMessagingServiceListener extends Firebase's <>FirebaseMessagingService class, which is used in order to receive Firebase's Device Token.
import com.appsflyer.AppsFlyerLib;
import com.google.firebase.messaging.FirebaseMessagingService;
public class MyNewFirebaseManager extends FirebaseMessagingService {
@Override
public void onNewToken(String s) {
super.onNewToken(s);
// Sending new token to AppsFlyer
AppsFlyerLib.getInstance().updateServerUninstallToken(getApplicationContext(), s);
// the rest of the code that makes use of the token goes in this method as well
}
}
That service should be added to AndroidManifest.xml in order to function: If the application was using FCM before integrating the AppsFlyer SDK, most chances are that this service has already been extended and the developer would just need to add the following line to the onNewToken()
method:
AppsFlyerLib.getInstance().updateServerUninstallToken(getApplicationContext(), refreshedToken);
Please also make sure you have added the relevant service to the AndroidManifest.xml:
<service
android:name=".MyNewFirebaseManager">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Solving Android uninstall push notification not being silent
Overriding Firebase's onMessageReceived
method and implementing your own logic in it might cause uninstall push notifications to not be silent. This can impact the user experience. To prevent that, check if the message contains af-uinstall-tracking
. See the following example:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(remoteMessage.getData().containsKey("af-uinstall-tracking")){
return;
} else {
// handleNotification(remoteMessage);
}
}
5. Using Proguard with uninstall measurement
If you are using ProGuard, add the following rule:
-dontwarn com.appsflyer.**
-keep public class com.google.firebase.messaging.FirebaseMessagingService {
public *;
}
6. Testing Android uninstall measurement
The Uninstalls metric is available in the Overview dashboard.
The list of users who uninstall the app is available in the uninstalls raw-data report.
To test Android uninstall measurement:
- Install the app.
- Uninstall the app. Note! You can uninstall the app immediately after installing it.
The uninstall event registers within 24 hours as uninstall measurement is processed daily.
If the app is reinstalled during this time - no uninstall event is recorded.
The app uninstall event takes up to 48 hours to show up in the raw-data reports and in the Aggregated Performance Report in your AppsFlyer dashboard.
Whether the Android app is live on Google Play, pending submission, or even out of store - the test is the same.
7. Disable uninstalls measurement
If a Firebase/GCM Server Key is provided, app uninstalls measurement is enabled by default. App owners can disable this feature via the dashboard.
Note! For an uninstall to be reported: Enable uninstalls measurement must be on at the time the app is installed. Installs occurring when Enable uninstalls measurement is off aren't reported.
To disable uninstalls measurement:
- In AppsFlyer, go to App settings.
- Scroll to Attribution > Uninstalls and turn off Enable uninstall measurement.
Note
The AppsFlyer iOS uninstall event data depends on the Apple Push Notification Service (APN). Due to privacy considerations, APN reports in real-time when a user removes an app only if at least eight days have passed since the install. This means that iOS uninstall data is available only after day 8.
Click here to learn more.
iOS uninstall measurement
Important!
To use this feature, you must have minimum SDK version 4.5.0 and higher. If you want to measure uninstalls on iOS 13 and above, you must have minimum SDK version 4.10.4 and higher.
This feature also requires a p12 certificate. p8 certificates are not supported.
Note
Uninstall measurement is not possible for users who reject Push Notification permissions.
1. Finding your app
2. If you have not registered an App ID yet, click the + symbol and complete the form.
3. Check the Push Notifications checkbox.
4. When you expand the application, there are two settings for push notifications with yellow or green status icons:
5. Click Settings to continue.
Note
The Settings button may be titled Edit if push notifications have been previously configured. If the Settings/Edit button is not available, you may not be the team agent or an admin. The person who originally created the developer account is your team agent and they carry out the remainder of the steps in this section.
2. Generating your certificate
1. Select Apple Push Notification service SSL (Sandbox & Production) in Production certificate option. If you are using VoIP for push notifications, select VoIP Services Certificate.
2. Click Create Certificate from the Production SSL Certificate option.
3. After clicking Create Certificate, note the Add iOS Certificate Assistant. Follow the instructions in the assistant and then click Continue.
4. Using the Certificate Signing request that was just created, generate the APNS Push SSL certificate.
5. Once the Download button appears, you are ready to download. You may need to reload the page for this to update. Download the newly created certificate:
6. Open the certificate. Opening the certificate will open Keychain Access.
In the Keychain Access, your certificate is shown under My Certificates. If not, check Certificates to see if it’s located there.
Note
Only account admins can upload or change the p12 certificate.
3. Renewing your certificate
If you are renewing either your Development or Production Push SSL Certificate, follow the steps outlined above as if you were uploading the certificate for the first time. There is no need to revoke the previous certificate in order to make this change. There may be two production certificates at the same time, to allow you to continue using the old certificate while uploading the new one.
4. Export the P12 File
The final step before heading back over to the AppsFlyer dashboard is to save your signing certificate as a .p12 file.
1. Select the certificate that was just added to Keychain Access
2. Go to File > Export Items.
3. Select My Certificates under the Category menu on the lower left-hand side.
If My Certificates is not highlighted, you cannot export the certificate as a .p12 file.
3. When saving the file, use the Personal Information Exchange (.p12) format.
4. Make sure it states Apple Push Services and appears as follows:
5. Go to your app's dashboard on the AppsFlyer platform.
6. Select App Settings on the left menu.
7. Click on the upload icon, select the P12 file to upload.
8. (optional) If the P12 certificate is password protected, fill in the password in the P12 certificate Password.
9. Click Validate to send the certificate to AppsFlyer to check if it is valid.
10. Click Save Settings.
5. Integrating with the SDK
Push notifications must be registered at the app's code level to enable uninstall data collection.
//add UserNotifications.framework
import UserNotifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//...
// iOS 10 support
if #available(iOS 10, *) {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
application.registerForRemoteNotifications()
}
// iOS 9 and iOS 8 support
else if #available(iOS 8, *), #available(iOS 9, *) {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
}
// iOS 7 support
else {
application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
}
return true
}
// Called when the application sucessfuly registers for push notifications
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
AppsFlyerTracker.shared().registerUninstall(deviceToken)
}
Add the following code to your AppDelegate.m:
- #import <UserNotifications/UserNotifications.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// The userNotificationTypes below is just an example and may be changed depending on the app
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
}];
[[UIApplication sharedApplication] registerForRemoteNotifications];
// if you do not use push notificaiton in your app, uncomment the following line
//application.applicationIconBadgeNumber = 0;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[AppsFlyerTracker sharedTracker] registerUninstall:deviceToken];
}
}
In AppDelegate.h, insert the following code to add UNUserNotificationCenterDelegate to the interface declaration:
#import <AppsFlyerLib/AppsFlyerTracker.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, AppsFlyerTrackerDelegate>
The code snippets above request permissions from the user to send push notifications. However, if you are only using push notifications in background mode to measure uninstalls, there is no need to ask for user approval. This is because these push notifications are silent push notifications that do not require you to ask permission from users.
User permission for push notifications in background mode
If you are only using silent push notifications, make sure to enable Remote Notifications in Background Modes in your app's Capabilities:
- In XCode, select your project
- Select your target
- Switch to Capabilities tab
- Toggle Background Modes on
- Check Remote notifications
6. Push notifications
Make sure you add Push Notification in your XCode capabilities tab. Without it, the deviceToken is not collected.
7. Testing uninstall
To test iOS uninstall measurement:
- Install the app.
- Uninstall the app. Note! You can uninstall the app immediately after installing it.
When testing uninstalls from Xcode or TestFlight it is important to let our SDK know that the token is generated from a Sandbox environment. Use the following APIs:
AppsFlyerTracker.shared().useUninstallSandbox = true
[AppsFlyerTracker sharedTracker].useUninstallSandbox = true;
Note! Uninstalls do not immediately appear in the AppsFlyer dashboard:
- It takes 9 days on average for uninstalls to appear in reports
- It can take more than a month for uninstalls originating from sandbox environments to appear in reports
In addition, the date of the uninstall is the date on which the uninstall is reported. See the next section to learn more.
8. Viewing uninstall data in the AppsFlyer dashboard
Uninstall measurement is displayed on the main dashboard in the Aggregated Performance table.
Due to a recent change in Apple Push Notification service, the time it takes uninstalls to appear on the dashboard is a minimum of 9 days. AppsFlyer updates and aggregates metrics for uninstalls every 24 hours
Example
- Day 1 - a user installs your app
- Day 4 - the user uninstalls your app
- Day 12 - Apple Push Notification Service reports app removal 8 days after the uninstall
- Day 13 - Uninstall data appear on AppsFlyer dashboard and raw data
For more details, refer to the iOS Measure App Uninstalls section of the SDK Integration Guide.
9. Disable uninstalls measurement
If a P12 certificate is provided and validated, app uninstalls measurement is enabled by default. App owners can disable this feature via the dashboard.
Note! For an uninstall to be reported: Enable uninstalls measurement must be on at the time the app is installed. Installs occurring when Enable uninstalls measurement is off aren't reported.
To disable uninstalls measurement:
- In AppsFlyer, go to App settings.
- Scroll to Attribution > Uninstalls and turn off Enable uninstall measurement.
Uninstall event postbacks
AppsFlyer enables you to send an uninstall event postback, for every known uninstalling user, to the partners you work with. The uninstall event is called af_uninstall
in AppsFlyer's dashboard.
Mapping the uninstall event
You can map the af_uninstall
event just like mapping any in-app event of your app.
As with any in-app event, AppsFlyer can send the postback only if the event actually occurs and is recorded by AppsFlyer. Therefore, mapping af_uninstall only works for completed uninstall implementations. If you don't see uninstalls in the overview page, or in the uninstalls raw data reports, no uninstall postbacks are sent to partners, even if you have mapped the af_uninstall
event.
af_uninstall
timing
Unlike postbacks for regular in-app events, The af_uninstall
event is not sent in real-time.
In AppsFlyer raw-data and partner postbacks, the af_uninstall
logged event time is the time when AppsFlyer knows about the uninstall.
- For Android devices: 24-48 hours after actual app uninstall
- For iOS devices: 9-11 days after actual app uninstall
Limitations
af_uninstall events are not included in In-app event postback reports.
The af_uninstall event is not currently available for all partners.
If you wish to map it with a partner, but see the event is not available for the partner, contact your dedicated CSM or write to hello@appsflyer.com.
If you are a partner and wish to receive af_uninstall events, contact your dedicated PDM or reach out to partners@appsflyer.com.