2

My firestore variables are saved by other names in cloud firestore. I think this is related to proguard, but I am not getting it.

Following are my username.

public String id;
public String name;
public String number;
public String profilePic;
public String shopPic;

and following is the screenshot, what is saved on firestore. sc

Here is some related code, which is very simple

        FirestoreUrls.get().getAccountsCollection()
                .document().set(binding.getUser()).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                hideProgressBar();
                handleFirebaseException(getClass(), task, true);
            }
        });
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212

3 Answers3

8

You are experiencing this problem because you are using Proguard for security, which shuffles the code so others cannot see it right after you create the app's APK. This is also available in the case of Firebase. To solve this, please add the following lines of code in your build.gradle file:

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

Then add the following rules in your project's Proguard file to prevent that behavior by replacing the package name with your own package name:

-keepattributes Signature //Global rule

-keepclassmembers class com.example.YourModelClass.** {
  *;
}

Please check the docs for more information:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • I checked this configuration, it is still same – Khemraj Sharma Mar 17 '20 at 10:16
  • Maybe [this](https://androidpedia.net/en/tutorial/4500/proguard-obfuscating-and-shrinking-your-code) can help you a little bit. – Alex Mamo Mar 17 '20 at 10:21
  • Not yet Alex Mamo – Khemraj Sharma Mar 18 '20 at 10:12
  • Hi @AlexMamo I'm facing the same problem and This solve my problem (Thanks) but the version of my app on google play still changing names. Should recreate a new APK and upload it to google play to solve the problem? – Amr Jyniat Jun 15 '20 at 09:33
  • @AmrJyniat Yes, a new APK as the files are now changed. – Alex Mamo Jun 15 '20 at 09:44
  • @AmrJyniat - can you please tell me what should I replace at the following line `-keepclassmembers com.example.YourModalClass.** { *; }` – CodeRED Innovations Jun 15 '20 at 18:12
  • @CodeREDInnovations The exact path to your model class in your package hierarchy. – Alex Mamo Jun 15 '20 at 18:24
  • 1
    @CodeREDInnovations try to remove the point after YourModalClass – Amr Jyniat Jun 16 '20 at 04:53
  • i have two modal classes how do i add them. i added two in the following manner `-keepclassmembers com.example.model.modelclassname -keepclassmembers com.example.model.modelclassname2` and it didn't worked still the app crashes. I'm sorry if this is a stupid issue to be raised but I want you to know that i'm not completely good at these. – CodeRED Innovations Jun 16 '20 at 08:03
  • What worked specifically for me was `-keepclassmembers class com.example.top-level-model-package.** { *; }` – keno Dec 29 '20 at 00:36
3

proguard renames fields and class names to shorter ones. To prevent this you can exclude this class from proguard optimizations with "-keep class com.package.MyClass" line in proguard-android.txt file.

But IMHO instead of this you should somewhere in your code map your variables to proper strings and then send strings to cloud firestore. Because for now any refactoring in your class (renaming fields for example) may broke your firestore name matching.

UPDATE:

It looks like you can map object fileds to proper strings this way:

User user = binding.getUser()

Map<String, Object> docData = new HashMap<>();
docData.put("id", user.id);
docData.put("name", user.name);
docData.put("number", user.number);
docData.put("profilePic", user.profilePic);
docData.put("shopPic", user.shopPic);

FirestoreUrls.get().getAccountsCollection()
                .document().set(docData)...
ashakirov
  • 12,112
  • 6
  • 40
  • 40
1
  • Ok, so I had the exact same problem and this is what I did to solve it.

Solution:

  • Go inside you your proguard-rules.pro file and paste this:
# Add this global rule
    -keepattributes Signature
-keep class <Your class package here>.** { *; }

  • The <Your class package here> can be found inside your class file:
package com.elliottsoftware.calftracker.domain.models.fireBase


//TODO THE GETTERS AND SETTERS USED BY FIREBASE ARE CASE SENSITIVE
data class FireBaseCalf(var calftag: String? = null,
                        var cowtag:String? = null,
                        var ccianumber: String? = null,
                        var sex:String? = null,
                        var details:String?=null,
                        var date: Date? = null,
                        var birthweight:String? = null,
                        var id: String? = null,

                        ) {
    // Null default values create a no-argument default constructor, which is needed
    // for deserialization from a DataSnapshot.
}

  • notice the com.elliottsoftware.calftracker.domain.models.fireBase, that is what you are going to replace with <Your class package here>

  • so in the end your proguard-rules.pro file will look like this:

# Add this global rule
    -keepattributes Signature

    -keep class com.elliottsoftware.calftracker.domain.models.fireBase.** { *; }

Tristan Elliott
  • 594
  • 10
  • 8