Cordova SDK - Uninstall Tracking

Uninstall Tracking

Track app uninstalls to measure user retention and optimize re-engagement campaigns by integrating push notification services with the Singular SDK.

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


Overview

How Uninstall Tracking Works

Uninstall tracking monitors app removals by registering push notification tokens with Singular. When devices no longer respond to push notifications, Singular identifies the app as uninstalled.

  • Android: Uses Firebase Cloud Messaging (FCM) tokens to detect uninstalls
  • iOS: Uses Apple Push Notification service (APNs) tokens to detect uninstalls
  • Data Accuracy: Provides insights into user retention and engagement over time

Android Uninstall Tracking

Prerequisites

Before implementing Android uninstall tracking, configure your app in the Singular platform following the Android Uninstall Tracking Setup Guide.

Requirements:

  • Android Version: Devices must run Android 4.1 (API 16) or higher
  • Google Play Services: Devices must have Google Play Store app installed
  • Firebase Setup: Firebase Cloud Messaging must be configured in your project
  • Permissions: Android 13+ requires explicit notification permission

Implementation Steps

Step 1: Install Firebase Plugin

Add a Firebase plugin to your Cordova project for push notification support. The cordova-plugin-firebase-messaging plugin is recommended.

bash
cordova plugin add cordova-plugin-firebase-messaging

For detailed Firebase setup instructions, see the plugin documentation.


Step 2: Configure Firebase

Add Firebase configuration files to your Cordova project for Android.

  1. Register your Android app in your Firebase Console project
  2. Download google-services.json and place it in your project root or platforms/android/app/
  3. Verify Firebase messaging dependencies are added to your project during plugin installation

Step 3: Request Notification Permission

Request notification permissions from users (required for Android 13+) before retrieving the FCM token.

JavaScript
document.addEventListener('deviceready', initializeApp, false);

function initializeApp() {
  if (device.platform === 'Android') {
    // Request notification permission (Android 13+)
    requestAndroidNotificationPermission();
  }
}

function requestAndroidNotificationPermission() {
  // Check Android version
  if (device.version >= 13) {
    cordova.plugins.permissions.requestPermission(
      cordova.plugins.permissions.POST_NOTIFICATIONS,
      function(status) {
        if (status.hasPermission) {
          console.log('Notification permission granted');
          retrieveAndRegisterFCMToken();
        } else {
          console.warn('Notification permission denied - uninstall tracking unavailable');
        }
      },
      function(error) {
        console.error('Permission request error:', error);
      }
    );
  } else {
    // Android 12 and below automatically have permission
    retrieveAndRegisterFCMToken();
  }
}

Note: To request permissions, install the cordova-plugin-android-permissions plugin:

cordova plugin add cordova-plugin-android-permissions

Step 4: Retrieve and Register FCM Token

Get the FCM device token and register it with Singular using the setUninstallToken() method after permissions are granted.

JavaScript
function retrieveAndRegisterFCMToken() {
  // Get FCM token
  cordova.plugins.firebase.messaging.getToken().then(function(token) {
    if (token) {
      console.log('FCM token retrieved:', token);
      
      // Register token with Singular for uninstall tracking
      cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
      
      console.log('FCM token registered with Singular');
    } else {
      console.warn('No FCM token available');
    }
  }).catch(function(error) {
    console.error('Error retrieving FCM token:', error);
  });
}

For complete method documentation, see setUninstallToken reference.


Step 5: Handle Token Refresh

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

JavaScript
document.addEventListener('deviceready', setupTokenRefreshListener, false);

function setupTokenRefreshListener() {
  if (device.platform === 'Android') {
    // Listen for FCM token refresh events
    cordova.plugins.firebase.messaging.onTokenRefresh(function(token) {
      console.log('FCM token refreshed:', token);
      
      // Update Singular with new token
      cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
    });
  }
}

Best Practice: FCM tokens can refresh at any time (app updates, device restore, etc.). Always subscribe to token refresh events to keep Singular updated with the latest token.


iOS Uninstall Tracking

Prerequisites

Configure your iOS app in the Singular platform following the iOS Uninstall Tracking Setup Guide.

Uninstall tracking on iOS uses Apple Push Notification service (APNs) technology. If your app doesn't support push notifications, see Apple's guide to Registering Your App with APNs.


Implementation Steps

Step 1: Request iOS Notification Authorization

Request notification permissions from the user and retrieve the APNS device token.

JavaScript
document.addEventListener('deviceready', initializeIOSTracking, false);

function initializeIOSTracking() {
  if (device.platform === 'iOS') {
    requestIOSNotificationPermission();
  }
}

function requestIOSNotificationPermission() {
  // Request iOS notification authorization
  cordova.plugins.firebase.messaging.requestPermission({
    forceShow: true
  }).then(function(hasPermission) {
    if (hasPermission) {
      console.log('iOS notification permission granted');
      retrieveAndRegisterAPNSToken();
    } else {
      console.warn('iOS notification permission denied - uninstall tracking unavailable');
    }
  }).catch(function(error) {
    console.error('Error requesting iOS notification permission:', error);
  });
}

Step 2: Retrieve and Register APNS Token

Get the APNS device token and register it with Singular using the setUninstallToken() method after authorization is granted.

JavaScript
function retrieveAndRegisterAPNSToken() {
  // Get APNS token (iOS)
  cordova.plugins.firebase.messaging.getToken().then(function(token) {
    if (token) {
      console.log('APNS token retrieved:', token);
      
      // Register token with Singular for uninstall tracking
      cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
      
      console.log('APNS token registered with Singular');
    } else {
      console.warn('No APNS token available');
    }
  }).catch(function(error) {
    console.error('Error retrieving APNS token:', error);
  });
}

Token Format: The APNS token retrieved from Firebase Messaging is already formatted correctly for Singular. No additional conversion is required.


Step 3: Handle Token Refresh (iOS)

Update the APNS token with Singular if it changes during the app lifecycle.

JavaScript
document.addEventListener('deviceready', setupIOSTokenRefreshListener, false);

function setupIOSTokenRefreshListener() {
  if (device.platform === 'iOS') {
    // Listen for APNS token refresh events
    cordova.plugins.firebase.messaging.onTokenRefresh(function(token) {
      console.log('APNS token refreshed:', token);
      
      // Update Singular with new token
      cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
    });
  }
}

Complete Cross-Platform Implementation

Unified Uninstall Tracking Setup

Implement uninstall tracking for both Android and iOS platforms with proper error handling and token refresh logic.

JavaScript
document.addEventListener('deviceready', initializeUninstallTracking, false);

function initializeUninstallTracking() {
  console.log('Initializing uninstall tracking for:', device.platform);
  
  // Setup token refresh listener for both platforms
  setupTokenRefreshListener();
  
  // Platform-specific initialization
  if (device.platform === 'Android') {
    setupAndroidUninstallTracking();
  } else if (device.platform === 'iOS') {
    setupIOSUninstallTracking();
  }
}

function setupAndroidUninstallTracking() {
  // Check Android version for permission requirements
  if (device.version >= 13) {
    // Request notification permission for Android 13+
    cordova.plugins.permissions.requestPermission(
      cordova.plugins.permissions.POST_NOTIFICATIONS,
      function(status) {
        if (status.hasPermission) {
          retrieveAndRegisterToken();
        } else {
          console.warn('Android notification permission denied');
        }
      },
      function(error) {
        console.error('Permission request error:', error);
      }
    );
  } else {
    // Android 12 and below - permission not required
    retrieveAndRegisterToken();
  }
}

function setupIOSUninstallTracking() {
  // Request iOS notification authorization
  cordova.plugins.firebase.messaging.requestPermission({
    forceShow: true
  }).then(function(hasPermission) {
    if (hasPermission) {
      retrieveAndRegisterToken();
    } else {
      console.warn('iOS notification permission denied');
    }
  }).catch(function(error) {
    console.error('Error requesting iOS permission:', error);
  });
}

function retrieveAndRegisterToken() {
  // Get push notification token (FCM for Android, APNS for iOS)
  cordova.plugins.firebase.messaging.getToken()
    .then(function(token) {
      if (token) {
        console.log('Token retrieved for ' + device.platform + ':', token);
        
        // Register token with Singular
        cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
        
        console.log('Token registered with Singular successfully');
      } else {
        console.warn('No token available for ' + device.platform);
      }
    })
    .catch(function(error) {
      console.error('Error retrieving token:', error);
    });
}

function setupTokenRefreshListener() {
  // Listen for token refresh events on both platforms
  cordova.plugins.firebase.messaging.onTokenRefresh(function(token) {
    console.log('Token refreshed for ' + device.platform + ':', token);
    
    // Update Singular with new token
    cordova.plugins.SingularCordovaSdk.setUninstallToken(token);
  });
}

Verification and Troubleshooting

Verify Implementation

Confirm uninstall tracking is working correctly before deploying to production.

  1. Check Logs: Verify token registration appears in your console logs with the correct format
  2. Test Token Generation: Ensure tokens are generated on first app launch after granting permissions
  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 when app relaunches

Common Issues

  • Token Not Generated: Verify Firebase plugin is correctly installed and Firebase is configured in your Cordova project
  • Permission Denied: Check that users have granted notification permissions (required for Android 13+ and all iOS versions)
  • Token Not Updating: Ensure you've subscribed to the onTokenRefresh event for both platforms
  • Missing Data: Confirm devices meet platform requirements (Android 4.1+ with Google Play Services, iOS with APNs support)
  • Configuration Error: Verify uninstall tracking is enabled in Singular platform settings for your app
  • Firebase Setup: For Android, ensure google-services.json is in the correct location. For iOS, ensure GoogleService-Info.plist is added to Xcode project

Best Practices

  • Request Permissions Early: Request notification permissions during onboarding or when user value is established
  • Handle Rejections Gracefully: Provide clear messaging when permissions are denied and explain the benefit to users
  • Test Both Platforms: Verify implementation works on both Android and iOS with different OS versions
  • Monitor Token Refresh: Always implement token refresh listeners to handle token updates automatically
  • Log for Debugging: Enable detailed logging during development to track token generation and registration