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

Posted

技术标签:

【中文标题】为啥在 Playstore 上发布我的应用程序后,firebase 会添加一个额外的日历节点?【英文标题】:Why is firebase adding an extra calendar node after publishing my app on playstore?为什么在 Playstore 上发布我的应用程序后,firebase 会添加一个额外的日历节点? 【发布时间】:2021-07-15 12:00:11 【问题描述】:

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

minifyEnabled true
shrinkResources true
useProguard true

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

-keepclassmembers class com.tubevibe.android.models.CampaignModel *;
-keepclassmembers class com.tubevibe.android.models.UserModel *;

从实时数据库获取数据时,此节点 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;
     

【问题讨论】:

请分享您的“CampaignModel”类的内容,包括包名。这两行代码是在哪个地方添加的? 谢谢你,亚历克斯,请检查,我已编辑。我只是不知道为什么在使用缩小和收缩资源后,它也将日历添加为节点。以 -keepclassmembers 开头的两行添加到 Android Studio 上的 proguard-rules.pro 中。 我决定从模型中删除日历代码,并在我的活动中使用它,在该活动中我推送值以在推送之前格式化我的发布日期。看起来在模型中有额外的代码是个坏主意。我将再次发布并检查。如果它有效,我将发布作为答案。谢谢,@AlexMamo 您的回复导致了这一点。 试一试,告诉我它是否有效。写另一个答案?它已经在那里了,我只是写了它;) 【参考方案1】:

如果您的“模型”包下有多个类,则只能使用以下行:

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

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

-keepattributes Signature
-keepattributes *Annotation*

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

Firebase firestore variable name changed

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

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

-keepnames class java.util.Calendar

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

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

【讨论】:

谢谢,这很有帮助,我会按照你在这里提出的建议进行一些更改。 好的,让我知道 ;) 是的(从你的模型类中获取“c”对象)这已经奏效了。我已经在游戏商店发布了它,并且发布得很好。我还在 proguard-rules.pro 中添加了“-keepattributes Annotation”语句。谢谢! :-) 不客气,kizito,很高兴听到它奏效了。【参考方案2】:

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

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

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

    明确告诉 Firebase 在读取/写入数据库时​​忽略该字段:

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

【讨论】:

感谢您指出这一点。如果我们仍然需要在模型中保留日历代码,这似乎是一种解决方法。我还没有尝试过,但将来也会考虑对此进行测试。这是一个很好的建议。 :-)

以上是关于为啥在 Playstore 上发布我的应用程序后,firebase 会添加一个额外的日历节点?的主要内容,如果未能解决你的问题,请参考以下文章

在 PlayStore 上发布后,Google 登录服务无法正常工作

在 playstore (SQLiteConnection.java) 上启动后,我的 Flutter 应用程序在多个设备上崩溃

在某些设备上从 PlayStore 下载后,Android App Bundle 崩溃

为啥我的 Flutter 应用在​​ Android 上请求 Run on Startup 权限?

我的 android 应用程序无法从最新设备上的 playstore 下载

将我的应用程序发布到 google playstore 后,我的应用程序无法获取 firestore 数据以回收分页视图