Класс не определяет конструктор без аргументов с isMinifyEnabled

Предоставленные ответы в дубликатах не помогли, так как я уже предоставил публичный конструктор для класса, который я даже защитил в 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"
        )
    }
}

Поскольку ProGuard все портит, вам нужно будет явно определить пустой конструктор и использовать его с @Keep, чтобы предотвратить его удаление, как описано в этом ответе.

samthecodingman 11.10.2023 03:21

Спасибо, добрый человек. Жаль, что модераторы stackoverflow закрыли вопрос и не поняли, что суть вопроса в другом.

AdisAlagic 11.10.2023 08:23

Ваш вопрос закрыл не модератор, его закрыл обычный пользователь с золотым значком в firebase. Модераторы являются избранными пользователями, и их можно отличить по синему ромбу после имени.

Mark Rotteveel 11.10.2023 10:04

Класс FirebaseTime, как показано, не имеет конструктора без аргументов, у него есть только конструктор с 4 аргументами.

Mark Rotteveel 11.10.2023 10:07

Он имеет значения по умолчанию, поэтому имеет конструктор без аргументов. В классе FirebaseTask вы можете видеть, что я использую конструктор без аргументов, иначе это было бы невозможно.

AdisAlagic 11.10.2023 10:29

Как я писал в вопросе, без isMinifyEnabled все работает нормально.

AdisAlagic 11.10.2023 10:38

Конструктор без аргументов будет определен как constructor() или FirebaseTime(), а не конструктор с четырьмя аргументами со значениями по умолчанию для каждого аргумента. Механизм отражения, используемый Firebase SDK, не будет использовать «конструктор с 4 аргументами и значениями по умолчанию», поскольку это не то же самое, что «конструктор без аргументов».

samthecodingman 11.10.2023 15:21

Тем не менее, я снова открыл вопрос после того, как он был закрыт, когда я связал его с другим ответом (как описано Марком выше). Модератор не имел права голоса. Это произошло потому, что у меня более 1000 голосов за вопросы и ответы, связанные с Firebase, поэтому ссылка на другой вопрос имела больше влияния, чем у обычных пользователей.

samthecodingman 11.10.2023 15:25
1
8
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, ответ дал 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,
    )
}

Другие вопросы по теме