[firebase-messaging] IOException: Invalid argument for the given fid
- Firebase Component: firebase-messaging
- Component version: 24.0.1
Describe the problem
Steps to reproduce:
For some users, attempting to get the token returns this error:
Fetching the token failed: java.util.concurrent.ExecutionException: java.io.IOException: Invalid argument for the given fid.
Here's a related issue that shows a full stack trace: https://github.com/firebase/firebase-android-sdk/issues/6914
Relevant Code:
FirebaseMessaging.getInstance().token
.addOnCompleteListener { task ->
if (!task.isSuccessful) {
val exception = task.exception
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed: ${exception?.message ?: "unknown"}", exception)
return@addOnCompleteListener
}
// ...
}
Note: I am using this through a library called expo-notifications, so you can see all the code here: https://github.com/expo/expo/blob/c46aeff68ecf6747d792b530482f2c88111cff39/packages/expo-notifications/android/src/main/java/expo/modules/notifications/tokens/PushTokenModule.kt#L51
I found a few problems with this issue:
- I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
- This issue does not seem to follow the issue template. Make sure you provide all the required information.
flutter app had same issus
Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: [firebase_messaging/unknown] java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: Invalid argument for the given fid.
at StandardMethodCodec.decodeEnvelope(message_codecs.dart:652)
at MethodChannel._invokeMethod(platform_channel.dart:370)
at MethodChannel.invokeMapMethod(platform_channel.dart:570)
at MethodChannelFirebaseMessaging.getToken(method_channel_messaging.dart:248)
We're seeing the same issue. The issue was (almost) gone during May, but it's occurred more often in the last two weeks. This completely breaks our app for new users, since it relies upon functioning push messages. Existing users seem unaffected, existing FCM tokens still work.
We're currently using com.google.firebase:firebase-messaging version 24.1.1 directly.
Hi folks! thank you for reaching out. I tried reproducing the issue, however, I did not encounter the same error. According to our engineers,
This registration error was returned because there were app instances in different devices using the same Firebase Installation ID (FID) to register FCM tokens. This happens generally because one app instance's firebase data was copied to an app instance in a different device.
This error is expected because of a recent change in FCM backend. FCM doesn't allow multiple devices to share the same FID because it will cause unpredicatble messasge delivery behaviors.
One solution is reinstall the app on the device that received this error. It will trigger a new FID to be generated.
With that, I'll be closing this issue now. For further investigation, it would be best to reach out to the Firebase support channel instead. We'd need access to your project settings (including projectID, SHA-1 etc) to troubleshoot this type of issue.
Thanks!
I was able to reproduce this on a device where the app was never installed before. A reinstall solved the issue on that device, but users have reported reinstalling does not solve the issue for them. At the moment my only explanation right now is that the FCM server is giving out duplicate IDs and then rejecting apps.
I have also contacted support and so far have not gotten any additional infos beyond the quote in https://github.com/firebase/firebase-android-sdk/issues/7025#issuecomment-2980433056
@lehcar09 thank you for the response.
But I have some concerns. As we are not the end user, we cannot reinstall the app.
Are you saying that this library doesn't support the basic Android feature "Set up & restore", where the app data will be copied to a new device (presumably along with the FID)? This seems like a big oversight.
I would appreciate if you could check with the engineers on how this common scenario should be handled, it doesn't seem specific to our app.
I also have users reporting that reinstalling the app does not solve the issue. The common denominator seems to be Android 15, but that may also be a coincidence.
I'm now able to consistently reproduce the issue by restoring a backup to two different emulators simultaneously. So this seems to be an issue with the dataExtractionRules/fullBackupContent settings of our app.
For the next update, we now added the following exclude rules:
<exclude
domain="sharedpref"
path="com.google.android.gms.appid.xml" />
<exclude
domain="sharedpref"
path="com.google.android.gms.measurement.prefs.xml" />
Plus one extra rule, which I'll explain below
EDIT: We're also automatically deleting FIDs after the update, see below https://github.com/firebase/firebase-android-sdk/issues/7025#issuecomment-2988251531
Strangely enough, however, the only hint I found that any backup rules may be necessary is buried here https://developer.android.com/identity/data/autobackup?hl=en#xml-include-exclude. AFAICT the Firebase documentation itself doesn't mention backup content anywhere. There is also no definitive list of which files need to excluded from backups.
IMO this is a severe bug in the com.google.firebase:firebase-messaging library. Why do I say that? Because of the extra rule we had to add:
<!-- See com.google.firebase.installations.local.PersistedInstallation.getDataFile() for how file name is constructed -->
<exclude
domain="file"
path="PersistedInstallation.W0RFRkFVTFRd+MTo0....JlZmJm.json" />
Note: I obfuscated the filename, because it contains the mobilesdk_app_id specific to your Firebase project.
https://github.com/firebase/firebase-android-sdk/blob/f08e0c72692ece9ef2d22489a111dc87f1216f34/firebase-installations/src/main/java/com/google/firebase/installations/local/PersistedInstallation.java#L83-L99
https://github.com/firebase/firebase-android-sdk/blob/f08e0c72692ece9ef2d22489a111dc87f1216f34/firebase-common/src/main/java/com/google/firebase/FirebaseApp.java#L518-L529
Again: IMO this is a severe bug in the com.google.firebase:firebase-messaging library. Why? If the file cannot be backed up and restored it should not be in appContext.getFilesDir() but in appContext.getNoBackupFilesDir() to avoid exactly this issue.
At the very least the FCM documentation should be updated, including an explanation of how the filename is generated.
The common denominator seems to be Android 15, but that may also be a coincidence.
We've seen the issue on Android 14 and Android 12 as well.
IIUC the bug was caused by a server-side change and this file can no longer be moved between devices. There may be a good reason for this change. But in that case, there should have been a new version of the FCM client library which moves this file into the no_backup directory and followed by a long deprecation period and ample warnings in release notes, etc..
I also have users reporting that reinstalling the app does not solve the issue.
My current assumption for this is, that either Google Play Store or the OS itself is restoring a cloud backup when reinstalling the app, or the manufacturer-specific Android variant has a feature to uninstall an app without removing app data and that also causes issues somehow.
We will instruct our users to use the "Clear storage" feature in the system settings app, which removes all app data and therefore ensures an actual fresh install.
Hi @kodebach, thank you for sharing your investigation findings. I was able to encounter the error after restoring the app backup on another emulator. And, this is expected because FCM doesn't allow multiple devices to share the same FID.
I tried uninstalling the app from emulator-1 before restoring the app on another emulator-2 and I was able to generate the token without any issue. On cases where re-installing the app did not resolve the issue, it's possible, that the app data was not removed.
To clarify, according to our Eng. the server-side change did not cause this issue. In the past, registrations of devices sharing the same FID were invalidated by FCM backend implicitly. After this change, we return an error explicitly in this case.
In addition to the exclusion rules for future backups, we are also going to update the app, so that it will detect the java.io.IOException: Invalid argument for the given fid error and delete it's FID. We haven't tested yet, whether calling deleteToken is necessary as well. That should fix the issue without requiring re-installation or deletion of app data. Though it will still require an app update.
This was suggested by Firebase support upon recommendation from their engineering team.
They also suggested using the Admin SDK to delete the FID, but that would only work if the server can get the FID before or when this error occurs, which is not case for us. But it might work for someone else.
according to our Eng. the server-side change did not cause this issue. In the past, registrations of devices sharing the same FID were invalidated by FCM backend implicitly. After this change, we return an error explicitly in this case.
IIUC previously the server silently assigned a new FID and FCM token. After the change, the FCM SDK an error is returned to the app instead, but nobody was told about this new error, or that we may need to handle it. To me that is a bug in the FCM SDK.
(If previously FCM would just silently stop working on one or both of the devices with the duplicate FID, then I agree it's actually bugfix and not a new bug. But app developers should still have been told about the new error.)
To be clear the docs for getToken() do not mention that the returned Task could fail with an exception that the needs to handle. Normally, when no exceptions are documented, it means you should just let it crash, because you can't do anything about it anyways. Also unless there was a change in the last two days, [this] is still one only place that mentions that FCM files need manual backup exclusions.
My main issue here is that this major (potentially breaking) change was not announced anywhere despite its major impact considering the widespread use of FCM.
On top of that there is of course the fact, that this whole fiasco was completely avoidable, if the FCM SDK had stored it's PersistedInstallation file in the no_backup directory where it belongs. So if anything the FCM SDK is not following the documented rules for Android development.
PS. @lehcar09 nothing against you personally, I assume you were and are following internal guidelines re closing of issues and referral to support. I'm just trying to point out that this seems like systemic failure for the Firebase team and you should internally re-evaluate how you could avoid issues like this in the future.
EDIT to add: I hope it is clear to your engineering team the error message Invalid argument for the given fid is now essentially part of the public API and changing it would be a(nother) breaking change. Changing the error message will cause this exact issue again in any app that now fixes the duplicate FID issue by detecting this error. (cf. Hyrum's Law)
Same issue
Hi folks! I have raised this issue again to our engineers for investigation and instruction. I'll get back you once I hear back from them. Thank!
@lehcar09 ok thank you, please keep us updated ASAP since this is a CRITICAL bug and currently have no way to resolve it. It is impacting many users and companies.
I seem to be encountering this problem in my app which was due to go live today for a large youth event happening next week. I saw that @kodebach mentioned deleting the FID but as I'm using Expo this doesn't appear to be an option for me. I have tried uninstalling and re-installing the app as has been suggested elsewhere but this doesn't work either.
I guess I'm looking for some reassurance that my understanding is correct in that
- The issue affects new devices as well as existing devices
- I cannot delete this by deleting the FID as I am using Expo
- I cannot refresh or clear anything locally on the device to workaround this
@fudjy deleting the FID doesn't fix it
@F170x @fudjy Did you try manually deleting the files I mentioned in https://github.com/firebase/firebase-android-sdk/issues/7025#issuecomment-2981625072? That worked for us, and should be possible no matter what framework you're using to develop your app.
@F170x @fudjy Did you try manually deleting the files I mentioned in #7025 (comment)? That worked for us, and should be possible no matter what framework you're using to develop your app.
I don't believe this is possible in an Expo app, but will admit I'm possibly out my depth (just a volunteer trying to make an app for 12k Scouts!)
@kodebach I didn't try deleting the files you mentioned.
I used the method delete from React Native Firebase https://rnfirebase.io/reference/installations#delete that internally uses this method https://firebase.google.com/docs/projects/manage-installations#javascript_1
I don't believe this is possible in an Expo app, but will admit I'm possibly out my depth (just a volunteer trying to make an app for 12k Scouts!)
I have zero experience with Expo, but I would guess, you need to call FileSystem.deleteAsync(FileSystem.documentDirectory + $file), where $file is the PersistedInstallation....json filename I described above. If that's not enough and the SharedPrefernces need to be deleted as well, you'll probably need something like https://www.npmjs.com/package/@wwdrew/expo-android-shared-preferences. No idea whether it works, but it mentions a clear(filename) function.
I used the method delete from React Native Firebase https://rnfirebase.io/reference/installations#delete that internally uses this method https://firebase.google.com/docs/projects/manage-installations#javascript_1
Yeah the delete method was recommended to us, by Firebase Support. If you follow the code, the FCM SDK first fires off a delete request to the server, and if that succeeds it replaces the local files with default/empty data. We didn't want to rely on the server request succeeding, so we simply delete the files, if delete() fails.
We don't have data yet, whether this solution works for all users. But in our tests with the backup/restore feature in Android Studio Canary, we saw that deleting the file works. That's also how I initially found out that you need to delete the annoyingly named PersistedInstallation....json
I was able to reproduce the issue using the following ADB steps:
- Have two emulators running (
emulator-5554andemulator-5556) - Install your APK on the first emulator
- Backup your app from the first emulator:
adb -s emulator-5554 backup -f myapp_backup.ab -noapk your.package - Install the same APK on the second emulator, but do not launch it
- Restore the backup to both emulators:
adb -s emulator-5554 restore myapp_backup.abadb -s emulator-5556 restore myapp_backup.ab - Launch the app on the second emulator (
emulator-5556)
At this point, I see the following error in the logs:
Topic sync or token retrieval failed on hard failure exceptions: java.util.concurrent.ExecutionException: java.io.IOException: Invalid argument for the given fid.. Won't retry the operation.
I also tried calling FirebaseMessaging.getInstance().deleteToken(), but it does not resolve the issue.
I was able to reproduce the issue using the following ADB steps:
Can confirm, that is basically what I did, but I used the new Backup/Restore feature in Android Studio Narwhal Feature Drop, which supports automatically restoring a backup when first installing the app.
Calling FirebaseInstallations.getInstance().getToken(true) seems to fix it by forcing a new token generation, but I'm not sure if that has side effects or might break other use cases. Would be great to get clarification on whether this is a valid workaround.
@pablojoseoroz Firebase support actually recommended FirebaseInstallations.getInstance().delete() not FirebaseMessaging.getInstance().deleteToken(). AFAICT calling deleteToken should do nothing, because I just saw that the FCM SDK has in fact some kind of check to detect a restored backup:
https://github.com/firebase/firebase-android-sdk/blob/acf250d9285be08a86cc95c0b0a265fce0f8a627/firebase-messaging/src/main/java/com/google/firebase/messaging/Store.java#L56-L80
The issue is only the FirebaseInstallations part of the SDK, whose authToken FCM uses. That authToken is deleted (and refreshed) by FirebaseInstallations.getInstance().getToken(true) so your solution might work, but I suspect it's still wrong. getToken(true) keeps the refreshToken and Installation ID and (potentially) sharing those between devices still seems very incorrect. So we will still use FirebaseInstallations.getInstance().delete() in our app.
For the engineering team: There is also existing logic specifically for duplicate IDs, but it seems the server does not send the appropriate response to trigger that logic
https://github.com/firebase/firebase-android-sdk/blob/acf250d9285be08a86cc95c0b0a265fce0f8a627/firebase-messaging/src/main/java/com/google/firebase/messaging/GmsRpc.java#L323-L330
That would at least result in a (somewhat) documented error on the client side. Even though it'd still require intervention from the app-side to resolve the issue.
Ideally of course the FirebaseInstallations SDK would have similar logic to the FCM Store code, or would just use getNoBackupFilesDir in general.
We are having the same issue.
Futter 3.29.2. firebase_messaging: 15.2.4 firebase_app_installations: 0.3.2+7 firebase_core: 3.12.1
More than 100k users are affected. We are testing/releasing a temporary fix. So far seems to be working:
We try await messaging.getToken();. If it fails with the fid error, we do await FirebaseInstallations.instance.delete(); and we retry again await messaging.getToken();. It successfully gets the token and notifications are working.
Hi folks! Thank you for your patience here. Just sharing an update here.
To recap, per our engineers,
This error was returned when there were app instances in different devices using the same Firebase Installation ID (FID) to register FCM tokens. This happens generally because one app instance's firebase data was copied to an app instance in a different device.
This error is expected because of a recent change in FCM backend. FCM has been more strict and now returns this error explicitly. In the past, registrations of devices sharing the same FID were invalidated by FCM backend implicitly. FCM doesn't allow multiple devices to share the same
For now, we have few suggestions to mitigate the issue:
- Deleting the FIS Id. However, please note, it does have some risks like impacting other devices because when you call FirebaseInstallations.getInstance().delete(), the FID is deleted on the service side so other devices holding the FID may also be impacted.
Firebase.messaging.token.addOnCompleteListener(
OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
// Check the exception
val exception = task.exception
if (exception is java.io.IOException) {
if (exception.message == "Invalid argument for the given fid.") {
Log.e(TAG, "FCM token fetch failed specifically due to: Invalid argument for the given fid.")
//Delete FIS ID to generate new one
FirebaseInstallations.getInstance().delete().addOnCompleteListener { task ->
if (task.isComplete) {
Log.d("Installations", "Installation deleted")
} else {
Log.e("Installations", "Unable to delete Installation")
}
}
Toast.makeText(baseContext, "Try again to generate token", Toast.LENGTH_SHORT).show()
}
}
return@OnCompleteListener
}
// Get new FCM registration token
val token = task.result
// Log and toast
val msg = getString(R.string.msg_token_fmt, token)
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
}
)
-
Deleting the PersistedInstallation....json file on the error (https://github.com/firebase/firebase-android-sdk/issues/7025#issuecomment-3000838021) might be a safer solution because it only deletes the data on the current device and the device will get a new FID when getToken() is called after that.
-
Adding the PersistentInstallation.--.json file in the data dataExtractionRules/fullBackupContent (suggested here android/7025#issuecomment-2981625072)
Per our engineers,
That is the only one you need to exclude. The filename is static for your Firebase app, so it will persist across installs.
Our engineers are working on the fix in Firebase Installation, however, I cannot provide any timeline when this will be released. I’ll let you know once this is released. Thanks!
@lehcar09 I don't think your code snippet would work. The IOException with the "Invalid argument for the given fid." message (thrown in GmsRpc) is actually wrapped in an ExecutionException by Tasks.await which is then wrapped in another IOException
https://github.com/firebase/firebase-android-sdk/blob/2bfc0a5de4c3d384238b25f9b71ef36104a72fa0/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java#L662-L666
So you need something like e is IOException && e.cause is ExecutionException && e.cause!!.cause is IOException and e.cause!!.cause!!.message == "Invalid argument for the given fid.".
We are also getting this issue for multiple users installing our apps on new devices. Reinstalling the app does not seem to have any effect.
Are you still able to reproduce the issue? Did the FCM Backend get an update?
We did not get any "Invalid argument for the given fid" error logs since 11 Jul 2025. Based on the low number of support tickets my company received last week I would have assumed that the issue got resolved? I am not able to reproduce the issue using emulators and backup/restore.
What are the recommended actions we should take for our app? Should we still exclude the PersistentInstallation.--.json file from backup?