Skip to main content

Uninstall Tracking through Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) uninstall tracking detects app uninstalls by monitoring FCM delivery receipts. This method is ideal for apps that already use push notifications.

End Goal

After completing this setup, you will call this method to send the FCM token to Apptrove:

AppTroveSDK.SendFcmToken(fcmToken);

How FCM Uninstall Tracking Works

  • Purpose: Tracks app uninstalls using FCM delivery receipts to assess user engagement and campaign performance
  • Mechanism: Uses FCM to send silent push notifications and monitors delivery receipts for failed deliveries
  • Detection: Uninstall data typically appears in the panel within 24-48 hours
  • Use Case: Measure uninstall rates for campaigns to refine targeting and improve user retention
Alternative Method

For Firebase Analytics-based uninstall tracking, see Through Firebase Analytics.

Prerequisites

Before implementing FCM uninstall tracking, ensure you have:

  • Firebase project with Cloud Messaging enabled
  • .NET MAUI app with Firebase SDK integrated
  • Apptrove SDK properly initialized
  • AppTroveSDK.Maui NuGet package installed

Implementation

1. Add Dependencies

Add Firebase Cloud Messaging dependencies to your .csproj:

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<PackageReference Include="Xamarin.Firebase.Messaging" Version="124.0.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.5" />
</ItemGroup>

Run to restore packages:

dotnet restore
Latest Version

Check the NuGet Gallery for the latest version and setup instructions.

2. Add google-services.json

  1. Go to the Firebase Console
  2. Select your project → Project settingsGeneral tab
  3. Download google-services.json for your Android app
  4. Place it in Platforms/Android/ folder
  5. Set build action in your .csproj:
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<GoogleServicesJson Include="Platforms\Android\google-services.json" />
</ItemGroup>

3. Initialize Apptrove SDK

Configure the Apptrove SDK in your App.xaml.cs:

using AppTroveSDK.Maui;

public partial class App : Application
{
public App()
{
InitializeComponent();
}

protected override async void OnStart()
{
base.OnStart();
await InitializeSDKAsync();
}

private async Task InitializeSDKAsync()
{
// Initialize SDK
var config = new AppTroveSDKConfig(
"YOUR_SDK_KEY",
AppTroveEnvironment.Production
);

AppTroveSDK.Initialize(config);

// Initialize FCM after SDK initialization
await InitializeFCMAsync();
}
}

4. Implement Firebase Cloud Messaging

Create the FCM helper class to handle FCM tokens.

Important - Call After SDK Initialization

Always call FCM initialization after the Apptrove SDK has been initialized. The SDK must be ready before sending the FCM token. Calling it before SDK initialization will result in the token not being properly registered.

Create Platforms/Android/PushNotificationHelper.cs:

using Firebase;
using Firebase.Messaging;
using AndroidTask = Android.Gms.Tasks.Task;

namespace YourApp.Platforms.Android;

public static class PushNotificationHelper
{
public static string? FcmToken { get; private set; }

/// <summary>
/// Get FCM token from Firebase Messaging
/// </summary>
public static async Task<string?> GetFcmTokenAsync()
{
try
{
Console.WriteLine("[FCM] Getting FCM token...");

// Initialize Firebase if not already done
var context = global::Android.App.Application.Context;
if (FirebaseApp.Instance == null)
{
Console.WriteLine("[FCM] Firebase not initialized, initializing...");
FirebaseApp.InitializeApp(context);
}

var tcs = new TaskCompletionSource<string?>();

FirebaseMessaging.Instance.GetToken()
.AddOnCompleteListener(new OnCompleteListener(task =>
{
if (task.IsSuccessful && task.Result != null)
{
var token = task.Result.ToString();
FcmToken = token;
Console.WriteLine($"[FCM] Token received: {token.Substring(0, Math.Min(20, token.Length))}...");
tcs.TrySetResult(token);
}
else
{
Console.WriteLine($"[FCM] Failed to get token: {task.Exception?.Message}");
tcs.TrySetResult(null);
}
}));

// Wait with timeout
var timeoutTask = Task.Delay(10000);
var completedTask = await Task.WhenAny(tcs.Task, timeoutTask);

if (completedTask == timeoutTask)
{
Console.WriteLine("[FCM] Token retrieval timed out");
return FcmToken;
}

return await tcs.Task;
}
catch (Exception ex)
{
Console.WriteLine($"[FCM] Error getting token: {ex.Message}");
return null;
}
}
}

/// <summary>
/// Helper class for Firebase task completion
/// </summary>
public class OnCompleteListener : Java.Lang.Object, global::Android.Gms.Tasks.IOnCompleteListener
{
private readonly Action<AndroidTask> _callback;

public OnCompleteListener(Action<AndroidTask> callback)
{
_callback = callback;
}

public void OnComplete(AndroidTask task)
{
_callback?.Invoke(task);
}
}

Add the FCM initialization in your App.xaml.cs:

/// <summary>
/// Initialize Firebase Cloud Messaging and send token to SDK
/// </summary>
private async Task InitializeFCMAsync()
{
#if ANDROID
try
{
var fcmToken = await Platforms.Android.PushNotificationHelper.GetFcmTokenAsync();

if (!string.IsNullOrEmpty(fcmToken))
{
AppTroveSDK.SendFcmToken(fcmToken);
Console.WriteLine($"[FCM] Token sent to Apptrove");
}
else
{
Console.WriteLine("[FCM] Token not available");
}
}
catch (Exception ex)
{
Console.WriteLine($"[FCM] Error initializing FCM: {ex.Message}");
}
#endif
}
FCM Token Behavior

FCM tokens are generated only once when the app is first installed or when Firebase generates a new token. If you run the app once and don't see the token in logs, you won't see it again on subsequent runs. To see the token again, you need to:

  1. Uninstall the app completely
  2. Reinstall the app
  3. Check logs immediately for the token

This is normal FCM behavior - tokens are not generated on every app launch, only when:

  • App is first installed
  • Firebase generates a new token (rare)
  • App data is cleared
  • App is restored on a new device

5. Firebase Console Configuration

Step 1: Connect Product to Firebase

If you haven't already connected your product to Firebase:

  1. Go to the Firebase Console
  2. Create a new project or select an existing one
  3. Add your Android app to the project
  4. After setting up the project on console, go to Settings
  5. In the General tab, see the Project ID and copy it

Step 2: Configure in Apptrove Panel

  1. Go to your Apptrove panel
  2. Navigate to Settings page
  3. Go to Uninstall Tracking tab
  4. Paste the Project ID you copied from Firebase Console
  5. Enable the toggle for uninstall tracking

Step 3: Enable Cloud Messaging API

  1. Go to the Cloud Messaging tab
  2. Check if Firebase Cloud Messaging API (V1) is enabled

If not enabled:

  1. Go to Service accounts tab

  1. Go to Library
  2. Search for Firebase Cloud Messaging API
  3. Click Enable

Step 4: Create Custom Role for Apptrove

  1. In the side menu, select Roles
  2. Click +Create role

  1. Complete the form as follows:
    • Title: Enter Apptrove Uninstall
    • ID: Enter at_uninstalls
    • Role launch stage: Select General availability
  2. Click Add permissions

  1. In the Filter field, search for: cloudmessaging.messages.create
  2. Select the permission and click Add
  3. Click Create
Verify Role Creation

After creating the role, check and verify that the Apptrove Uninstall role has been added successfully with the cloudmessaging.messages.create permission.

Step 5: Assign Apptrove the FCM Uninstall Role

  1. In the side menu, select IAM
  2. Click Grant Access

  1. In Add PrincipalsNew principals, enter: at-uninstalls-tracking-tra-430@trackier-mmp.iam.gserviceaccount.com
  2. In Assign rolesRole select Custom and choose Apptrove Uninstall (the role we created earlier)
  3. Click Save
Service Account Email

Use this exact email address: at-uninstalls-tracking-tra-430@trackier-mmp.iam.gserviceaccount.com

Step 6: Verify Permissions

  1. Go to IAM & AdminIAM
  2. Search for the service account you just added
  3. Verify that the Apptrove Uninstall role is assigned

Verification and Testing

1. Test FCM Token Registration

When your app starts, check the logs to verify the FCM token is being sent to Apptrove:

Check Token Response: Look for the log message Fcm token Api response saved successfully

Expected Log Output:

D/trackiersdk: Fcm token Api response saved successfully

2. Test Uninstall Detection

  1. Install your app and register FCM token
  2. Uninstall the app
  3. Wait 24-48 hours for the uninstall data to be processed
  4. Check Apptrove dashboard for uninstall event

3. Monitor Apptrove Dashboard

  1. Log in to your Apptrove dashboard
  2. Navigate to uninstall logs
  3. Confirm the uninstall event was received (typically within 24-48 hours)
Uninstall Data Processing Time

Uninstall events are not detected immediately. It typically takes 24-48 hours for uninstall data to appear in the Apptrove panel after an app is uninstalled. This is normal behavior for FCM-based uninstall tracking.

Important Notes

FCM Token Behavior
  • Token Generation: FCM tokens are generated when the app is first installed or when the token is refreshed
  • Token Refresh: Tokens can change when:
    • App is restored on a new device
    • App data is cleared
    • App is uninstalled and reinstalled
    • Token expires (rare)
  • One-Time Call: Token refresh listener is called only when a new token is generated, not on every app launch
Silent Notifications Only

Apptrove uses silent push notifications solely to measure uninstalls or identify inactive users and does not use them for any other purposes. These notifications are invisible to users and don't affect app performance.

Troubleshooting

Common Issues

  • FCM token not received: Ensure Firebase is properly configured with google-services.json in Platforms/Android/ directory and Firebase packages are added
  • Uninstall not detected: Check server logs for FCM delivery failures and verify token registration
  • Token not sent to Apptrove: Ensure FCM initialization is called after SDK initialization
  • Rate limiting: Implement proper delays between FCM sends to avoid Google's rate limits
  • Token expiration: Handle token refresh events to update the token

Best Practices

  • Silent notifications: Use silent push notifications to avoid user disruption
  • Rate limiting: Implement proper delays to avoid FCM rate limits
  • Token management: Handle FCM token refresh and updates properly
  • Error handling: Implement comprehensive error handling for FCM failures
  • Security: Store FCM tokens securely on your server
  • Call Order: Always initialize FCM after Apptrove SDK initialization

Debug Steps

  1. Verify Firebase Setup:

    dotnet clean
    dotnet restore
    dotnet build -t:Run -f net10.0-android
  2. Check Logcat:

    adb logcat -s trackiersdk
  3. Verify Dependencies: Ensure Firebase packages are properly added in .csproj

  4. Check Firebase Console: Verify your app is registered and FCM API is enabled

  5. Test Token Retrieval: Add debug prints to verify the token is being retrieved:

    var token = await PushNotificationHelper.GetFcmTokenAsync();
    Console.WriteLine($"DEBUG: FCM Token received: {token}");
    AppTroveSDK.SendFcmToken(token);

For further assistance, refer to the Apptrove Documentation Portal or contact support at support@trackier.com.