Предоставленные ответы в дубликатах не помогли, так как я уже предоставил публичный конструктор для класса, который я даже защитил в proguard-rules.pro, что всё равно не помогло. Вот почему я задал новый вопрос о переполнении стека.
У меня есть база данных Firebase Realtime. Когда я использую режим отладки, все работает нормально, но когда я начал использовать isMinifyEnabled = true, я начал получать эту ошибку:
(Я пытаюсь проанализировать снимок из Firebase)
com.google.firebase.database.DatabaseException: класс com.adisalagic.taskmanagerhelper.objects.FirebaseTask$FirebaseTime не определяет конструктор без аргументов. Если вы используете ProGuard, убедитесь, что эти конструкторы не удалены.
Мой класс FirebaseTask:
@Keep
data class FirebaseTask(
val id: String = UUID.randomUUID().toString(),
val name: String = "",
val start: FirebaseTime = FirebaseTime(),
val end: FirebaseTime? = null,
val workDay: Boolean = false
) {
data class FirebaseTime(
val nano: Long = 0,
val second: Long = 0,
val minute: Long = 0,
val hour: Long = 0,
)
}
На всякий случай вот моя FirebaseCheckedTask:
@Keep
data class FirebaseCheckedTask(
val date: String = LocalDate.MIN.toString(),
val task: FirebaseTask = FirebaseTask(),
val checked: Boolean = false
)
Как видите, у меня есть конструктор без аргументов. Вероятно, проблема связана с ProGuard, но ни одно из существующих решений по Stack Overflow мне не помогло.
Мой файл ProGuard:
-keepclassmembers class com.google.firebase.database.GenericTypeIndicator { *; }
-keepattributes Signature
-keepclassmembers class com.test.finalapp.Models.** {
*;
}
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-repackageclasses
# Firebase https://github.com/firebase/firebase-android-sdk/issues/4900
-keep public class com.google.firebase.** { *;}
-keep class com.google.android.gms.internal.** { *;}
-keepclasseswithmembers class com.google.firebase.FirebaseException
-keep class * extends com.google.firebase.database.GenericTypeIndicator { *; }
-keepclassmembers public class * extends com.adisalagic.taskmanagerhelper.objects.FirebaseTask {
<init>(...);
*;
}
-keepclassmembers public class * extends com.adisalagic.taskmanagerhelper.objects.FirebaseCheckedTask {
<init>(...);
*;
}
-keepclassmembers public class * extends com.adisalagic.taskmanagerhelper.objects.FirebaseTask$FirebaseTime{
<init>(...);
*;
}
Firebase SDK, который я использую:
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-database-ktx")
Вот также конфигурация сборки:
buildTypes {
debug {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
Спасибо, добрый человек. Жаль, что модераторы stackoverflow закрыли вопрос и не поняли, что суть вопроса в другом.
Ваш вопрос закрыл не модератор, его закрыл обычный пользователь с золотым значком в firebase. Модераторы являются избранными пользователями, и их можно отличить по синему ромбу после имени.
Класс FirebaseTime, как показано, не имеет конструктора без аргументов, у него есть только конструктор с 4 аргументами.
Он имеет значения по умолчанию, поэтому имеет конструктор без аргументов. В классе FirebaseTask вы можете видеть, что я использую конструктор без аргументов, иначе это было бы невозможно.
Как я писал в вопросе, без isMinifyEnabled все работает нормально.
Конструктор без аргументов будет определен как constructor() или FirebaseTime(), а не конструктор с четырьмя аргументами со значениями по умолчанию для каждого аргумента. Механизм отражения, используемый Firebase SDK, не будет использовать «конструктор с 4 аргументами и значениями по умолчанию», поскольку это не то же самое, что «конструктор без аргументов».
Тем не менее, я снова открыл вопрос после того, как он был закрыт, когда я связал его с другим ответом (как описано Марком выше). Модератор не имел права голоса. Это произошло потому, что у меня более 1000 голосов за вопросы и ответы, связанные с Firebase, поэтому ссылка на другой вопрос имела больше влияния, чем у обычных пользователей.
Итак, ответ дал samthecodingman
Вам необходимо явно определить конструктор с аннотацией @Keep. Вы можете сделать это следующим образом:
@Keep
data class FirebaseTask @Keep constructor(
val id: String = UUID.randomUUID().toString(),
val name: String = "",
val start: FirebaseTime = FirebaseTime(),
val end: FirebaseTime? = null,
val workDay: Boolean = false
) {
data class FirebaseTime @Keep constructor(
val nano: Long = 0,
val second: Long = 0,
val minute: Long = 0,
val hour: Long = 0,
)
}
Поскольку ProGuard все портит, вам нужно будет явно определить пустой конструктор и использовать его с
@Keep, чтобы предотвратить его удаление, как описано в этом ответе.