Android SDK - Uninstall Tracking

Uninstall Tracking

Track app uninstalls to measure user retention and optimize re-engagement campaigns by integrating Firebase Cloud Messaging (FCM) with the Singular SDK.

Important: Google deprecated GCM APIs in April 2018. Use Firebase Cloud Messaging (FCM) for all uninstall tracking implementations.

Prerequisites

Configure Singular Platform

Before implementing uninstall tracking in your app, configure your app in the Singular platform and complete the Android SDK + FCM integration steps described in Setting Up Android Uninstall Tracking .


System Requirements

Uninstall tracking requires Firebase Cloud Messaging and specific device configurations.

FCM Requirements ( source ):

  • Android Version: Devices must run Android 4.1 (API 16) or higher
  • Google Play Services: Devices must have the Google Play Store app installed
  • Emulator Support: Android 4.1+ emulators with Google APIs are supported
  • Distribution: Apps can be distributed outside the Google Play Store while still supporting uninstall tracking

Note: Users on unsupported Android versions or devices without Google Play Services will not be tracked for uninstalls.


Implementation Steps

Step 1: Integrate Firebase Cloud Messaging

Set up Firebase Cloud Messaging in your app if not already configured.

Follow Google's official guide to Set up a Firebase Cloud Messaging client app on Android . This includes:

  1. Add Firebase to your Android project
  2. Add the FCM SDK dependency to your app/build.gradle
  3. Create a Firebase Messaging Service class
  4. Request notification permissions (Android 13+)

Step 2: Confirm AndroidManifest.xml FCM Setup

Verify FCM Service and Permissions

Ensure your app is already integrated with Firebase Cloud Messaging and that the Android manifest declares a FirebaseMessagingService to receive FCM messages.

XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.your.package">

    <!-- FCM Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application>

        <!-- App Firebase Messaging Service -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

    </application>

</manifest>

Important: Replace .MyFirebaseMessagingService with the fully qualified name of your class that extends FirebaseMessagingService . Only one service should handle the com.google.firebase.MESSAGING_EVENT intent in your app.


Step 3: Register FCM Device Token

Retrieve the FCM device token and send it to Singular for uninstall tracking.

Retrieve and Set Token

Get the FCM token and register it with Singular immediately after SDK initialization.

Kotlin Java
import com.google.firebase.messaging.FirebaseMessaging
import com.singular.sdk.Singular

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // Initialize Singular SDK
        val config = SingularConfig("SDK_KEY", "SDK_SECRET")
        Singular.init(applicationContext, config)
        
        // Retrieve and register FCM token
        FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w("FCM", "Fetching FCM token failed", task.exception)
                return@addOnCompleteListener
            }
            
            // Get FCM token
            val token = task.result
            
            // Register token with Singular
            Singular.setFCMDeviceToken(token)
            Log.d("FCM", "FCM token registered with Singular: $token")
        }
    }
}

Best Practice: Register the FCM token immediately after Singular.init() to ensure uninstall tracking is enabled from the first app session.

Singular.setFCMDeviceToken() silently no-ops if it is called before Singular.init() completes or if the token argument is null or empty. If your token registration appears to do nothing, confirm that the SDK was initialized first and that the FCM token returned by Firebase is a non-empty string.


Handle Token Refresh

Update the FCM token with Singular whenever it refreshes to maintain accurate uninstall tracking.

Kotlin Java
import com.google.firebase.messaging.FirebaseMessagingService
import com.singular.sdk.Singular

class MyFirebaseMessagingService : FirebaseMessagingService() {
    
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        
        // Send updated token to Singular
        Singular.setFCMDeviceToken(token)
        Log.d("FCM", "New FCM token registered: $token")
        
        // Also send token to your server if needed
        sendTokenToServer(token)
    }
    
    private fun sendTokenToServer(token: String) {
        // Implement your server communication logic here
    }
}

Important: FCM tokens can refresh at any time (app updates, device restore, etc.). Always implement onNewToken() to keep Singular updated.


Alternative Configuration Method

Set Token During Initialization

If you have the FCM token available before SDK initialization, configure it in the SingularConfig object.

Kotlin Java
// Get token synchronously (if cached)
val cachedToken = getStoredFCMToken() // Your caching logic

val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withFCMDeviceToken(cachedToken)

Singular.init(applicationContext, config)

Method Signature:

public SingularConfig withFCMDeviceToken(String fcmDeviceToken);

withFCMDeviceToken only seeds the SDK with the token you have at initialization time. It does not subscribe to token refreshes. You still need to implement FirebaseMessagingService.onNewToken and call Singular.setFCMDeviceToken(newToken) there to keep Singular's record current. The config method also no-ops silently if the supplied token is null or empty.


Verification and Troubleshooting

Verify Implementation

Confirm uninstall tracking is working correctly.

  1. Check Logs: Verify FCM token registration appears in your logs
  2. Test Token Generation: Ensure tokens are generated on first app launch
  3. Monitor Dashboard: Check Singular dashboard for uninstall tracking data after 24-48 hours
  4. Test Token Refresh: Clear app data and verify token updates correctly

Common Issues

  • Token Not Generated: Verify FCM dependencies are correctly added and Firebase is configured in your project
  • Token Not Updating: Check that onNewToken() callback is implemented in your FirebaseMessagingService
  • Missing Data: Ensure devices meet FCM requirements (Android 4.1+, Google Play Services installed)
  • Configuration Error: Confirm uninstall tracking is enabled in Singular platform settings

Additional Resources: For detailed troubleshooting, see the Uninstall Tracking Setup Guide and Firebase Cloud Messaging Documentation .