Android手机镜像克隆后Firebase Cloud Messaging设备标识异常问题求助
First, let's break down how FCM generates unique tokens for devices, then walk through concrete steps to fix your cloning issue.
How FCM Tokens Are Generated
FCM relies on Firebase Installations (the replacement for the older Instance ID system) to create a unique identifier for each device-app combination. This ID, which maps directly to your FCM token, is generated using a mix of:
- Device-level identifiers (like the
ANDROID_ID—while Android 8.0+ makes this app-scoped, mirroring can still copy system-level identifiers that Google Play Services relies on) - Google Play Services' internal persistent storage (which stores a unique installation ID tied to the original device)
- Your app's signature and package name
When you clone a device, if you copy over the persistent storage for Firebase Installations or Google Play Services, all cloned devices will share the same underlying ID—resulting in identical FCM tokens, even after clearing app data.
Why Your Previous Fixes Didn't Work
Clearing app data and stopping processes only resets your app's local token cache. It doesn't touch the Firebase Installations ID stored in Google Play Services' system-level storage, nor does it reset device-level identifiers that might be mirrored across devices. That's why you're still seeing duplicate tokens.
Step-by-Step Solutions
1. Force Reset Firebase Installations ID in Your App
Add code to your app to detect when it's running on a cloned device (e.g., check for a cloning flag, or detect duplicates via your server) and trigger a reset of the Firebase Installations ID. This will force a new token to be generated:
// Kotlin example FirebaseInstallations.getInstance().delete() .addOnCompleteListener { task -> if (task.isSuccessful) { // Fetch the new token immediately after deletion FirebaseMessaging.getInstance().token.addOnSuccessListener { newToken -> // Update your server with this new unique token uploadTokenToServer(newToken) } } }
Run this code only once per cloned device (e.g., on first launch after cloning) to avoid unnecessary token churn. For Java, adapt the callback syntax to match the language.
2. Wipe Google Play Services' System Storage
After cloning, use an ADB command to fully clear Google Play Services data (requires root or device owner privileges for bulk deployment):
adb shell pm clear com.google.android.gms
Then restart the device. This removes the cached Firebase Installations ID tied to the original device.
3. Exclude Sensitive Directories from Your Mirror
When creating your base device image, exclude these directories to avoid copying persistent identifiers:
- Your app's private storage:
/data/data/[your-app-package-name] - Google Play Services' private storage:
/data/data/com.google.android.gms - Firebase Installations storage subdirectories (under the above GMS folder)
4. Use Enterprise-Grade Deployment Tools (For Bulk Scenarios)
If you're deploying dozens/hundreds of devices, skip manual cloning and use Android Enterprise EMM tools or Managed Google Play. These tools automatically handle device identifier resetting, ensuring each device gets a unique FCM token out of the box—no manual fixes needed.
5. Add Server-Side Token Validation
Implement a check on your backend to detect duplicate FCM tokens. When a duplicate is found, send a signal to the app to trigger the Firebase Installations reset logic. This acts as a safety net for any devices that slip through the cloning workflow.
内容的提问来源于stack exchange,提问作者mtopley

