Android Firebase 使用字母键存储自定义对象成员(例如 "a" , "b" , "c" ) 仅在通过发布 apk 安装时



对于大多数类来说,这都可以正常工作,但特别是对于一个类,我在使用该对象调用 setValue() 后得到这个结果,其中也添加了正确命名的键。这会混淆我在此位置设置的侦听器并导致奇怪的行为。不过,似乎不会发生在任何其他类中,无论出于何种原因,它仅在我安装发布 apk 时发生。调试时工作正常(普通键名)。

"stats":{
  "a" : 0,
  "b" : 0,
  "c" : 0,
  "d" : 0,
  "e" : 0,
  "hp" : 5,
  "level" : 1,
  "maxHp" : 5,
  "xp" : 0
}

球员统计.class

public class PlayerStats implements Serializable {
    public static final int START_MAX_HP = 5;
    public int gold;
    public int level;
    public int xp;
    public int hp;
    public int maxHp;
    public PlayerStats() {}
    public PlayerStats(int gold, int level, int xp, int hp, int maxHp) {
        this.gold = gold;
        this.level = level;
        this.xp = xp;
        this.hp = hp;
        this.maxHp = maxHp;
    }
    /**
     * Calculates what the next xp threshold is to level up for the player based on their level
     * @param level The player's level
     * @return xp required to reach the next level
     */
    public static int getNextXpGoal(int level) {
        int x = level + level - 1;
        return (int) (x * Math.log((double)x) * 10 + 100);
    }
    public int getGold() {
        return gold;
    }
    public int getMaxHp() {
        return maxHp;
    }
    public int getHp() {
        return hp;
    }
    public int getLevel() {
        return level;
    }
    public int getXp() {
        return xp;
    }
}

导致上述结果的代码段:

// Update player stats
    final DatabaseReference statsRef = ref.child("users").child(uid).child("stats");
    statsRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getValue() != null) {
                PlayerStats stats = dataSnapshot.getValue(PlayerStats.class);
                int hpLost = FailQuestAsyncTask.calculateHpLost(stats.hp, quest.difficulty);
                stats.hp -= hpLost;
                // Save new stats
                statsRef.setValue(stats);
            }
        }
        @Override
        public void onCancelled(DatabaseError firebaseError) {
        }
    });

我不知道为什么会这样。我找不到任何证据表明这种情况发生在其他人身上。

编辑:我想出了为什么我得到上面的奇怪结果。我直接设置"stats"的成员,而不是在一种方法中传递一个新对象。但是,我仍然对为什么Firebase在运行发布apk时使用这种按字母顺序排列的命名方案感兴趣。

您是否在发布版本上运行 Proguard?它可能正在修改类名,然后使用类名写入数据库。在你的build.gradle中寻找一些东西,比如:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt')
    }
}

您可以在项目的 Proguard 文件中添加 Proguard 规则以防止模型被修改,将包名称替换为您自己的模型包:

# 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.** {
  *;
}

有关更多详细信息,请参阅文档。

最新更新