54

When using the Firebase SDK for Android apps, I keep getting warnings and errors like these (in Eclipse):

Warning ... can't find referenced class ...
Warning: there were ... unresolved references to classes or interfaces ...
You may need to specify additional library jars (using '-libraryjars') ...

Unfortunately, Firebase doesn't have any official documentation about its use with ProGuard.

What directives do I need for my apps to successfully compile releases with Firebase when obfuscated with ProGuard?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
caw
  • 30,999
  • 61
  • 181
  • 291
  • See also [Configure ProGuard](https://firebase.google.com/docs/database/android/start/#proguard) – Kato Jan 09 '17 at 22:17
  • Unfortunately, this did not resolve the Firebase issue for the Coinverse app. You may see the full code [here](https://github.com/AdamSHurwitz/Coinverse). – AdamHurwitz Apr 13 '20 at 23:34
  • 1
    Is there a similar configuration for Firebase Firestore databases using ProGuard as there is when using a Realtime database, outlined in the _[Configure Proguard](https://firebase.google.com/docs/database/android/start/#proguard)_ section? – AdamHurwitz Aug 07 '20 at 06:47

12 Answers12

55

Based on my personal tests, it turned out something along these lines is necessary for Firebase-enhanced Android apps to compile with ProGuard.

In any case, you have to add -keepnames class com.my.package.beans.** { *; } if you are using custom objects in your Firebase, i.e. beans or POJOs.

Firebase SDK 1.0.18:

-keepnames class com.firebase.** { *; }
-keepnames class com.shaded.fasterxml.jackson.** { *; }
-keepnames class org.shaded.apache.** { *; }
-keepnames class javax.servlet.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.commons.logging.impl.**

Firebase SDK 1.1.1:

-keep class com.firebase.** { *; }
-keep class org.shaded.apache.** { *; }
-keepnames class com.shaded.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**

Firebase SDK 2.0.0:

-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**

# Only necessary if you downloaded the SDK jar directly instead of from maven.
-keep class com.shaded.fasterxml.jackson.** { *; }

Last resort:

-keep class !com.my.package.** { *; }

Notes:

Any official guideline would be welcome. The -dontwarn directives are obviously dangerous, code may break at points that I have not tested. Furthermore, the above rules are quite permissive and other rules may better optimize your APKs.

Michael Lehenbauer
  • 16,229
  • 1
  • 57
  • 59
caw
  • 30,999
  • 61
  • 181
  • 291
  • @JennyTong: Thanks! Any explanation for the changes? I can't find any `org.apache.**` or `com.fasterxml.jackson.**` classes in the SDK, only the `shaded` versions. – caw Dec 16 '14 at 04:48
  • 2
    I had to add `-keepattributes Signature` to let jackson work properly. Ref: http://stackoverflow.com/questions/28433281/how-to-include-typereference-proguard-rule – Riccardo Casatta Mar 16 '15 at 10:15
  • @RiccardoCasatta You're right, this is required. I just forgot to mention it because I have this attribute, anyway. – caw Mar 16 '15 at 15:06
  • 1
    From our Slack channel: "you will need to add the following line if you're using FirebaseUI: `-dontwarn com.firebase.ui.auth.**`" – Frank van Puffelen Mar 09 '16 at 01:52
  • 1
    You saved my day with "if you are using custom objects in your Firebase, i.e. beans or POJOs". My app was crashing on production cause not having this rule. Thanks!! – Billyjoker Mar 09 '19 at 18:19
  • If you use AdMob add `-keep class com.google.android.gms.internal.** { *; }` this will fix *IllegalArgumentException: Stack size becomes negative after instruction [23] invokestatic #46 in [com/google/android/gms/internal/ads/zzaq.zzf(Ljava/lang/String;)J]* – Kirill Karmazin Jun 19 '19 at 14:03
  • i didn't know what BEAN/POJOS mean, lol googled it, Beans/Pojos are called model classes in java, i.e for encapsulating data. thought it might be helpful for others like me :D – Nasib Dec 05 '19 at 18:37
  • Unfortunately, this did not resolve the Firebase issue for the Coinverse app. You may see the full code [here](https://github.com/AdamSHurwitz/Coinverse). – AdamHurwitz Apr 13 '20 at 23:33
  • `@Keep` annotation can also be used to preserve data classes. Tested and works for Firebase: https://developer.android.com/guide/navigation/navigation-pass-data#use_keep_annotations – secretshardul Sep 10 '20 at 06:33
16

I found this in Firebase documentations:

When using Firebase Realtime Database in your app along with ProGuard you need to consider how your model objects will be serialized and deserialized after obfuscation. If you use DataSnapshot.getValue(Class) or DatabaseReference.setValue(Object) to read and write data you will need to add rules to the proguard-rules.pro file:

# Add this global rule    
-keepattributes Signature

# This rule will properly ProGuard all the model classes in 
# the package com.yourcompany.models. Modify to fit the structure
# of your app.
-keepclassmembers class com.yourcompany.models.** {
*;
}
MrAliB
  • 799
  • 9
  • 17
  • 1
    Could you provide a link to the documentation? – SalicBlu3 Mar 15 '17 at 15:44
  • 1
    @SalicBlu3, here is the documentation: https://firebase.google.com/docs/database/android/start#proguard. – AdamHurwitz Apr 13 '20 at 22:31
  • Unfortunately, this did not resolve the Firebase issue for the [Coinverse app](https://github.com/AdamSHurwitz/Coinverse). – AdamHurwitz Apr 13 '20 at 23:21
  • `@Keep` annotation can also be used to preserve data classes. Tested and works for Firebase: https://developer.android.com/guide/navigation/navigation-pass-data#use_keep_annotations – secretshardul Sep 10 '20 at 06:32
14

2021 answer

Use @Keep annotation before your data classes so they're retained by proguard. It's a part of AndroidX for both Java and Kotlin. Works for Firebase, Jetpack Navigator and Retrofit.

@Keep
data class Listing(
    val id: String = "",
    val name: String = ""
)

According to documentation:

Denotes that the annotated element should not be removed when the code is minified at build time. This is typically used on methods and classes that are accessed only via reflection so a compiler may think that the code is unused.

secretshardul
  • 1,635
  • 19
  • 31
9

It's not really official documentation, but Firebase did show some basic proguard rules in one of their Github repositories. https://github.com/firebase/AndroidChat/blob/master/app/proguard-rules.pro

# Basic ProGuard rules for Firebase Android SDK 2.0.0+
-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.apache.**
-dontwarn org.w3c.dom.**
user4989692
  • 1,609
  • 1
  • 20
  • 25
  • Thanks for this source! The differences to my configuration (see other answer) seems to be that they dropped the `dontwarn` rules for `org.joda.time.**`, `org.shaded.apache.**` and `org.ietf.jgss.**` and instead included one for `org.apache.**`. – caw Jul 06 '15 at 01:13
  • You're welcome. Just wanted to add it since it was from Firebase itself and also since it was slightly different from your personal tests. – user4989692 Jul 06 '15 at 02:33
3

Following up on the other answers, using Firebase 2.4.1 I only had to include the following in my proguard config (YMMV):

-keep class com.firebase.** { *; }
-dontwarn com.fasterxml.**
Eliezer
  • 7,209
  • 12
  • 56
  • 103
3

The configuration for firebase 2.5.2 seems changed. This is what is working for me:

-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.shaded.fasterxml.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.apache.**
-dontwarn org.w3c.dom.**
Ugo Chirico
  • 347
  • 3
  • 6
2

My working set for Firebase SDK 2.4.2:

-keep class com.firebase.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**
-dontwarn com.firebase.**
-dontnote com.firebase.client.core.GaePlatform
Peter
  • 10,910
  • 3
  • 35
  • 68
  • So it's just the last four entries that are new, right? Maybe a `-dontwarn com.firebase.**` is sufficient here? – caw Mar 04 '16 at 01:30
1

I also struggled with this. Thanks to user4989692 and Ugo for pointing me the right direction.

Here is what worked for me:

build.gradle

    buildTypes {
    debug {
        minifyEnabled false
        shrinkResources false
        useProguard false
        debuggable true
        signingConfig signingConfigs.debug
    }
    release {
        minifyEnabled true
        shrinkResources true
        useProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

proguard-rules.pro

-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**
-dontwarn com.firebase.**
-dontnote com.firebase.client.core.GaePlatform

-keepattributes Signature
-keepattributes *Annotation*
-keepattributes InnerClasses,EnclosingMethod

-keep class com.YOUR-APP-DOMAIN.** { *; }

# Basic ProGuard rules for Firebase Android SDK 2.0.0+
-keep class com.firebase.** { *; }

-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
Lee Hounshell
  • 842
  • 9
  • 10
  • 18
    won't keep com.YOUR-APP_DOMAIN simply disable all of Proguard? This seems really wrong. – domenukk Jul 12 '16 at 17:11
  • 1
    According to firebase you need instead: -keepclassmembers class com.yourcompany.models.** { *; } just the models you are using together with the real time database! – Tino Jul 12 '16 at 18:45
1

If you are using Firebase Realtime Database, the model objects will be serialized and deserialized after obfuscationstrong text

-keep class com.yourdevelopername.urappname.** { *; }
Azmat Ali
  • 554
  • 5
  • 7
  • Did the approach in the [documentation](https://firebase.google.com/docs/database/android/start#proguard) not work for you @Kaiffi? – AdamHurwitz Apr 13 '20 at 22:32
  • Unfortunately, this did not resolve the Firebase issue for the Coinverse app. You may see the full code [here](https://github.com/AdamSHurwitz/Coinverse). – AdamHurwitz Apr 13 '20 at 23:32
1

This is why when you do clean architecture is easy to fix, look at this scenario, if I had multiple firebase requests from multiple files in my app it would be a mess to try to keep single classes for firebase to work, so, if we have a modularized code and we store all our requests and data model inside a data layer it would be so much easy to keep just the classes that uses firebase instead of the whole project, doing this will be better to shrink more the apk size also

enter image description here

-keep class com.mypackage.data.** {*;}
Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
0

It solves my problem

Add this to your proguard-rules file

-optimizations !class/merging/*
Masum
  • 4,879
  • 2
  • 23
  • 28
  • Unfortunately, this did not resolve the Firebase issue for the Coinverse app. You may see the full code [here](https://github.com/AdamSHurwitz/Coinverse). – AdamHurwitz Apr 13 '20 at 23:29
0

I have added the same ones that everyone has shown:

# Firebase
-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.apache.**
-dontwarn org.w3c.dom.**

But I also have this one that I discovered by myself, because I couldn't find anyone who added it:

-keep class com.google.android.gms.** { *; }

And the firebase services work perfectly for me:

Dynamic Link, FireStorage, Auth, Realtime DataBase, Firestore

Chuy Porras
  • 125
  • 1
  • 6