-
Notifications
You must be signed in to change notification settings - Fork 633
Description
- Android Studio version: Android Studio Narwhal | 2025.1.1 Patch 1
- Firebase Component: Common
- Component version: 22.0.0
Steps to reproduce:
I don't think this can be easily reproduced, but I was trying to track what could be causing this error on our app (we have tens of reports of this issue per day):
androidx.datastore.preferences.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at androidx.datastore.preferences.protobuf.CodedInputStream$StreamDecoder.readTag(SourceFile:26)
at androidx.compose.ui.text.input.GapBuffer.getFieldNumber(SourceFile:56)
at androidx.datastore.preferences.protobuf.MessageSchema.mergeFrom(SourceFile:5)
at androidx.datastore.preferences.PreferencesProto$PreferenceMap.parseFrom(SourceFile:41)
at androidx.datastore.preferences.core.PreferencesFileSerializer.readFrom(SourceFile:1)
at androidx.datastore.core.FileReadScope.readData$suspendImpl(SourceFile:98)
at androidx.datastore.core.DataStoreImpl$data$1$5.invokeSuspend(SourceFile:131)
at androidx.datastore.core.DataStoreImpl$data$1$5.invoke(SourceFile:105)
at androidx.datastore.core.FileStorageConnection.readScope(SourceFile:93)
at androidx.datastore.core.DataStoreImpl.readDataFromFileOrDefault(SourceFile:17)
at androidx.datastore.core.DataStoreImpl.access$readDataOrHandleCorruption(SourceFile:223)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invokeSuspend(SourceFile:128)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invoke(SourceFile:14)
at androidx.datastore.core.SingleProcessCoordinator.lock(SourceFile:94)
at androidx.datastore.core.DataStoreImpl.readAndInitOrPropagateAndThrowFailure(SourceFile:96)
at androidx.datastore.core.DataStoreImpl.access$handleUpdate(SourceFile:155)
at androidx.datastore.core.DataStoreImpl$writeActor$3.invokeSuspend(SourceFile:33)
at androidx.datastore.core.DataStoreImpl$writeActor$3.invoke(SourceFile:13)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend(SourceFile:86)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:9)
at kotlinx.coroutines.DispatchedTask.run(SourceFile:115)
at com.google.android.gms.tasks.zzc.run(SourceFile:11)
at kotlinx.coroutines.scheduling.TaskImpl.run(SourceFile:3)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(SourceFile:88)
androidx.datastore.core.CorruptionException: Unable to parse preferences proto.
at androidx.datastore.preferences.core.PreferencesFileSerializer.readFrom(SourceFile:316)
at androidx.datastore.core.FileReadScope.readData$suspendImpl(SourceFile:98)
at androidx.datastore.core.DataStoreImpl$data$1$5.invokeSuspend(SourceFile:131)
at androidx.datastore.core.DataStoreImpl$data$1$5.invoke(SourceFile:105)
at androidx.datastore.core.FileStorageConnection.readScope(SourceFile:93)
at androidx.datastore.core.DataStoreImpl.readDataFromFileOrDefault(SourceFile:17)
at androidx.datastore.core.DataStoreImpl.access$readDataOrHandleCorruption(SourceFile:223)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invokeSuspend(SourceFile:128)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invoke(SourceFile:14)
at androidx.datastore.core.SingleProcessCoordinator.lock(SourceFile:94)
at androidx.datastore.core.DataStoreImpl.readAndInitOrPropagateAndThrowFailure(SourceFile:96)
at androidx.datastore.core.DataStoreImpl.access$handleUpdate(SourceFile:155)
at androidx.datastore.core.DataStoreImpl$writeActor$3.invokeSuspend(SourceFile:33)
at androidx.datastore.core.DataStoreImpl$writeActor$3.invoke(SourceFile:13)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend(SourceFile:86)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:9)
at kotlinx.coroutines.DispatchedTask.run(SourceFile:115)
at com.google.android.gms.tasks.zzc.run(SourceFile:11)
at kotlinx.coroutines.scheduling.TaskImpl.run(SourceFile:3)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(SourceFile:88)
Since DefaultHeartBeatController uses the com.google.android.gms.tasks
mentioned in the stacktrace above and it underneath uses HeartBeatInfoStorage
which in turns contains a JavaDataStorage
instance using preferences data stores I think this could be the root cause, since apparently this data store has no protections against data corruption.
As far as I can tell, Firebase is the only library using this com.google.android.gms.tasks
dependency in our codebase.
Relevant Code:
You can find the code here.
private val Context.dataStore: DataStore<Preferences> by
preferencesDataStore(
name = name,
produceMigrations = { listOf(SharedPreferencesMigration(it, name)) }
)
As you can see the corruption handler is missing. If I'm not mistaken this means apps can crash with a CorruptionException
as soon as any component using this data store are used (such as com.google.firebase.heartbeatinfo.HeartBeatInfoStorage
).