为什么在 Playstore 上发布我的应用程序后,firebase 会添加一个额外的日历节点?

问题描述

使用这些优化发布我的应用后;

minifyEnabled true
shrinkResources true
useProguard true

Firebase 将我来自 CampaignModel 类的日历代码视为一个节点,并将其作为“c”添加到数据中,其中包含所有当前时间详细信息。我已经使用 Proguard 排除了我所有的类模型:

-keepclassmembers class com.tubevibe.android.models.CampaignModel {*;}
-keepclassmembers class com.tubevibe.android.models.usermodel {*;}

enter image description here

从实时数据库获取数据时,此节点 c 导致我的应用程序崩溃。有什么办法可以阻止日历中的这个节点被插入吗?

这是我的广告系列模型

package com.tubevibe.android.models;

import androidx.annotation.Keep;
import java.util.Calendar;

@Keep
public class CampaignModel {
    private String id;
    private String idNo;
    private String videoUrl;
    private String viewsNeeded;
    private String totalCost;
    private String active;
    private String timerequired;
    private Long postingDate;


    Calendar c = Calendar.getInstance();
    int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);

    public CampaignModel() {
    }

    public CampaignModel(String id,String idNo,String videoUrl,String viewsNeeded,String totalCost,String active,String timerequired) {
        this.id = id;
        this.idNo = idNo;
        this.videoUrl = videoUrl;
        this.viewsNeeded = viewsNeeded;
        this.totalCost = totalCost;
        this.active = active;
        this.timerequired = timerequired;
        this.postingDate = c.getTimeInMillis() - utcOffset;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getIdNo() {
        return idNo;
    }

    public void setIdNo(String idNo) {
        this.idNo = idNo;
    }

    public String getViewsNeeded() {
        return viewsNeeded;
    }

    public void setViewsNeeded(String viewsNeeded) {
        this.viewsNeeded = viewsNeeded;
    }

    public String getTotalCost() {
        return totalCost;
    }

    public void setTotalCost(String totalCost) {
        this.totalCost = totalCost;
    }

    public String getTimerequired() {
        return timerequired;
    }

    public void setTimerequired(String timerequired) {
        this.timerequired = timerequired;
    }

    public String getVideoUrl() {
        return videoUrl;
    }

    public void setVideoUrl(String videoUrl) {
        this.videoUrl = videoUrl;
    }

    public Long getPostingDate() {
        return postingDate;
    }

    public void setPostingDate(Long postingDate) {
        this.postingDate = postingDate;
    }

    public String getActive() {
        return active;
    }

    public void setActive(String active) {
        this.active = active;
    } 
}

解决方法

如果您的“models”包下有多个类,那么您只能使用以下行:

-keepclassmembers class com.tubevibe.android.models.* {*;}

因为我看到您在“CampaignModel”类中使用了“@Keep”注释,这是正确的,因此也必须将以下两行代码添加到您的“proguard-rules.pro”文件中:

-keepattributes Signature
-keepattributes *Annotation*

就在上述代码行之前。请记住,您之所以会出现这种行为,是因为您正在使用 Proguard 来确保安全性,它会在您创建应用的 APK 之后对代码进行混洗,以便其他人无法看到它:

适用于 Cloud Firestore,但适用相同的规则。

此外,“日历”类不是 Firebase 实时数据库 supported data-type。我还没有测试过,但很可能您还需要添加以下行:

-keepnames class java.util.Calendar

如果这不起作用,很可能您应该从模型类中取出“c”对象并创建它的新实例,仅在您需要它的类中。这样,对象“c”将不再出现在数据库中。

要查看它是否正常工作,请使用更改后的代码再次发布应用。

,

Alex 解释了为什么 c 会出现在您的数据库中,但我想指出另外两种方法来确保它不会出现。

  1. 将该字段标记为 private,这意味着 Firebase 在读取/写入数据库时​​会忽略它:

    private Calendar c = Calendar.getInstance();
    private int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
    
  2. 明确告诉 Firebase 在读取/写入数据库时​​忽略该字段:

    @Exclude
    private Calendar c = Calendar.getInstance();
    @Exclude
    private int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);