Firebase @PropertyName 不起作用

Posted

技术标签:

【中文标题】Firebase @PropertyName 不起作用【英文标题】:Firebase @PropertyName doesn't work 【发布时间】:2016-12-05 11:53:54 【问题描述】:

故事

我在我的应用中使用 Firebase 实时数据库。我有一个类似这样的模型。

class Item 
    int mItemName;
    // Simplified for brevity

现在,这会将字段作为itemName 存储在我的实时数据库中。但我不想使用该命名约定。我希望命名模式是这样的,item_name

我做了什么

我像这样在字段上方使用了@PropertyName("item_name"),

class Item 
        @PropertyName("item_name")
        int mItemName;
        // Simplified for brevity
    

问题

Firebase 似乎完全忽略了注释。我无法更改序列化和反序列化的属性名称。

任何帮助将不胜感激。

编辑

这是完整的模型类,

public class FileModel 

        @PropertyName("file_id")
        String mFileId;
        @PropertyName("file_name")
        String mOriginalFileName;
        @PropertyName("file_path")
        String mFilePath;
        @PropertyName("file_type")
        String mFileType;
        @PropertyName("last_modified")
        Long mFileLastModified;
        @PropertyName("file_size")
        String mFileSize;
        @Exclude
        private boolean mIsSelected;

        /**
         * Must have empty constructor for JSON deserialization by Firebase
         */
        public FileModel() 
        

        public FileModel(String fileId, String originalFileName,
                                    String filePath, String fileType, Long fileLastModified, String fileSize) 
            this.mFileId = fileId;
            this.mOriginalFileName = originalFileName;
            this.mFilePath = filePath;
            this.mFileType = fileType;
            this.mFileLastModified = fileLastModified;
            this.mFileSize = fileSize;
        

        public String getFileId() 
            return mFileId;
        

        public void setFileId(String fileId) 
            this.mFileId = fileId;
        

        public String getOriginalFileName() 
            return mOriginalFileName;
        

        public void setOriginalFileName(String originalFileName) 
            this.mOriginalFileName = originalFileName;
        

        public String getFilePath() 
            return mFilePath;
        

        public void setFilePath(String filePath) 
            this.mFilePath = filePath;
        

        public String getFileType() 
            return mFileType;
        

        public void setFileType(String fileType) 
            this.mFileType = fileType;
        

        public Long getFileLastModified() 
            return mFileLastModified;
        

        public void setFileLastModified(Long fileLastModified) 
            this.mFileLastModified = fileLastModified;
        

        public String getFileSize() 
            return mFileSize;
        

        public void setFileSize(String fileSize) 
            this.mFileSize = fileSize;
        

        public boolean getIsSelected() 
            return mIsSelected;
        

        public void setIsSelected(boolean isSelected) 
            this.mIsSelected = isSelected;
        

        @Override
        public boolean equals(Object o) 
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            FileModel model = (FileModel) o;

            if (mIsSelected != model.mIsSelected) return false;
            if (mFileId != null ? !mFileId.equals(model.mFileId) : model.mFileId != null) return false;
            if (mOriginalFileName != null ? !mOriginalFileName.equals(model.mOriginalFileName) : model.mOriginalFileName != null)
                return false;
            if (mFilePath != null ? !mFilePath.equals(model.mFilePath) : model.mFilePath != null)
                return false;
            if (mFileType != null ? !mFileType.equals(model.mFileType) : model.mFileType != null)
                return false;
            if (mFileLastModified != null ? !mFileLastModified.equals(model.mFileLastModified) : model.mFileLastModified != null)
                return false;
            return mFileSize != null ? mFileSize.equals(model.mFileSize) : model.mFileSize == null;

        

        @Override
        public int hashCode() 
            int result = mFileId != null ? mFileId.hashCode() : 0;
            result = 31 * result + (mOriginalFileName != null ? mOriginalFileName.hashCode() : 0);
            result = 31 * result + (mFilePath != null ? mFilePath.hashCode() : 0);
            result = 31 * result + (mFileType != null ? mFileType.hashCode() : 0);
            result = 31 * result + (mFileLastModified != null ? mFileLastModified.hashCode() : 0);
            result = 31 * result + (mFileSize != null ? mFileSize.hashCode() : 0);
            result = 31 * result + (mIsSelected ? 1 : 0);
            return result;
        

        @Override
        public String toString() 
            return "FileModel" +
                    "mFileId='" + mFileId + '\'' +
                    ", mOriginalFileName='" + mOriginalFileName + '\'' +
                    ", mFilePath='" + mFilePath + '\'' +
                    ", mFileType='" + mFileType + '\'' +
                    ", mFileLastModified=" + mFileLastModified +
                    ", mFileSize='" + mFileSize + '\'' +
                    ", mIsSelected=" + mIsSelected +
                    '';
        
    

【问题讨论】:

您的 build.gradle 文件中包含什么版本的 Firebase 数据库? 如果你的班级public?字段是“公开的”吗?没有这两个,它不会被序列化为 JSON。 我使用的是最新版本 9.2.1。类和字段都是公共的,它们也是序列化的,只是不遵守更改属性名称的注释。 查看 Frank 在此线程上的回答:***.com/questions/37330156/… 显然,他们错过了此版本中的 PropertyName 注释。但他们将在下一次更新中包含它。 您能否发布您的整个课程定义作为答案的编辑?然后我就很容易调试了。 【参考方案1】:

Kotlin 数据类的解决方案:

data class Pojo (@get:PropertyName("fieldName") @set:PropertyName("fieldName") var field: String = "")

【讨论】:

救了我的命!在这里工作得很好! 也适合我。属性必须是 vars,并且必须同时具有 set 和 get 注释。 @AriLacenski 与 Cloud Firestore 一起使用带有单个 @PropertyName 注释的 val 可以正常工作,如下所示:data class Pojo(@PropertyName("fieldName") val field: String = "")。尚未针对实时数据库对其进行测试 多么丑陋的解决方案.. 但它有效。谢谢!【参考方案2】:

终于有机会解决这个问题了。感谢 @hatboysam 的建议。

唯一的问题是,@PropertyName 注释未正确记录在 Firebase 中。

首先需要的是该字段必须是public否则注释将不起作用,这很明显/

现在注释考虑了字段名称以及要序列化的 getter/setter 名称。我还遇到了字段以及 getter/setter 被序列化的问题,导致重复的键/值对

我通过使用公共字段名称上的注释并忽略 getter/setter 解决了这个问题。这完美地解决了这个问题。没有用我想要的属性名正确序列化数据,也没有重复数据问题。

这是一个简单的例子,

    class Item 

        @PropertyName("item_no")
        int mItemNo;
        // Simplified for brevity

        @Exclude
        public int getItemNo()
              return mItemNo;
        

        @Exclude
        public void setItemNo(int itemNo)
              this.mItemNo = itemNo;
        
    

【讨论】:

如果字段是公开的,那么你就不需要 getters&setters 我喜欢保留 getter/setter 而不是访问任何公共字段。有时我需要在这些访问器方法中进行格式更改。 这似乎不适用于枚举 - 有人让它工作吗?【参考方案3】:

或者,只需使用 @PropertyName 标记您的 getter,而不是自己注释属性 - 这样您可以在提供自定义名称的同时保持属性私有:

public class User extends Object 

    private String mDisplayName;


    @PropertyName("userName")
    public String getDisplayName() 
        return mDisplayName;
    

    @PropertyName("userName")
    public void setDisplayName(String displayName) 
        mDisplayName = displayName;
    


【讨论】:

【参考方案4】:

如果您使用的是 JAVA 并且其他解决方案不适合您,那么这绝对可以!

我想要这样,每个变量的第一个字母都以大写开头。

public class CommentModel 

@PropertyName("BuyerID")
Integer buyerId;
@PropertyName("Message")
String message;
@PropertyName("Name")
String name;
@PropertyName("Photo")
String photo;
@PropertyName("SellerID")
Integer sellerId;

public CommentModel() 



@PropertyName("BuyerID")
public Integer getBuyerId() 
    return buyerId;


@PropertyName("BuyerID")
public void setBuyerId(Integer buyerId) 
    this.buyerId = buyerId;


@PropertyName("Message")
public String getMessage() 
    return message;


@PropertyName("Message")
public void setMessage(String message) 
    this.message = message;


@PropertyName("Name")
public String getName() 
    return name;


@PropertyName("Name")
public void setName(String name) 
    this.name = name;


@PropertyName("SellerID")
public Integer getSellerId() 
    return sellerId;


@PropertyName("SellerID")
public void setSellerId(Integer sellerId) 
    this.sellerId = sellerId;


@PropertyName("Photo")
public String getPhoto() 
    return photo;


@PropertyName("Photo")
public void setPhoto(String photo) 
    this.photo = photo;



注意,这里@PropertyName("")com.google.firebase.database.PropertyName

【讨论】:

以上是关于Firebase @PropertyName 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云功能 - onCall 不起作用

Flutter Web 在 Firebase 托管中不起作用

Firebase 推送通知点击不起作用

为啥这个 Firebase“.indexOn”不起作用?

Firebase 动态链接,不起作用

角度应用程序中的 Firebase 功能不起作用