'Firebase @PropertyName doesn't work
THE STORY
I am using Firebase Realtime Database in my app. I have a model something like this.
class Item {
int mItemName;
// Simplified for brevity
}
Now, this stores the field as itemName in my real time database. But I don't want to use that naming convention. I want the naming pattern to be this, item_name.
WHAT I DID
I used the @PropertyName("item_name") above the field like this,
class Item {
@PropertyName("item_name")
int mItemName;
// Simplified for brevity
}
THE PROBLEM
Firebase seems to just ignore the annotation completely. There is no way I am able to change the property names for serialization and deserialization.
Any help would be highly appreciated.
EDIT
Here is the complete model class in concern,
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 +
'}';
}
}
Solution 1:[1]
Finally got a chance to solve this problem. Thanks to @hatboysam for the suggestion.
The only problem was, @PropertyName annotation was not properly documented in Firebase.
The first thing that is necessary is the the field must be public otherwise the annotation will not work, which is quite obvious/
Now the annotation takes into account both the field name as well as the getter/setter names to serialize. I also had the problem where the fields as well as the getter/setters were getting serialized, resulting in duplicate key/value pairs.
I solved the problem by using the annotation on the field name which were public and ignoring the getter/setters. This solved the problem perfectly. Not the data was properly serialized with the property name I wanted and there was no duplicate data problem as well.
Here is a simple example,
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;
}
}
Solution 2:[2]
Solution for Kotlin data class:
data class Pojo (@get:PropertyName("fieldName") @set:PropertyName("fieldName") var field: String = "")
Solution 3:[3]
Alternatively just mark your getters with @PropertyName instead of annotating properties themselves - this way you can keep properties private while providing custom names:
public class User extends Object {
private String mDisplayName;
@PropertyName("userName")
public String getDisplayName() {
return mDisplayName;
}
@PropertyName("userName")
public void setDisplayName(String displayName) {
mDisplayName = displayName;
}
}
Solution 4:[4]
If you're using JAVA and the other solutions not working for you then this will definitely work!
I wanted like this where every variable's first letter started with Capital.
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;
}
}
Note that, here @PropertyName("") is com.google.firebase.database.PropertyName
Solution 5:[5]
The Kotlin solution for data classes with immutable fields :
data class Item(
@get:PropertyName("item_name")
val mItemName: Int = 0 // Simplified for brevity
)
The Kotlin solution for data classes with mutable fields :
data class Item(
@set:PropertyName("item_name")
@get:PropertyName("item_name")
var mItemName: Int = 0 // Simplified for brevity
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | pvpkiran |
| Solution 2 | Hammer |
| Solution 3 | |
| Solution 4 | Kishan Solanki |
| Solution 5 | Julian Paul |

