7

I created an object to send some data to firebase. As an example, I use firebase user example:

public class User {
    public String username;
    public String email;

    public User() {
        // Default constructor required for calls to DataSnapshot.getValue(User.class)
    }

    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }
}

I want to encode property names that are sent to firebase. Currently keys are sent using variable names. I want to encode keys something like Useraname and Email, like Gson is doing. I don't want to change variable names.

@SerializateName("Username")
public String username;
@SerializateName("Username")
public String email;

I used @SerializateName(), but is not working. Same with @PropertyName that is used by Firebse, is not working. What I can use in order to serializare custom keys?

Update 1

public class Pojo {
    @PropertyName("Guid")
    public String guid;

   @PropertyName("Name")
   public String name;

   public String getPojoGuid() {
       return guid;
   }

   public void setPojoGuid(String guid) {
       this.guid = guid;
   }
}

As you can see in the image, it saves keys based on variable names. I changed property name from annotation for one field and when i save it, it ignores it, but when i change variable name, it save as new entry with key for that new varialbe name.

enter image description here

In this documentation is a method toMap(). If i do like that, is working (is not convenient for me), but is not working with @PropertyName.

Update 2

If i mark getters and setters with @Exclude and class with @IgnoreExtraProperties is working. I don't have to use toMap() method example from documetation. Is using specified name from @PropertyName. Not a good thing in my opinion, create confuses.

4
  • 1
    @PropertyName works for me with version 11.0.2 of the SDK. What version are you using?
    – Bob Snyder
    Commented Jul 25, 2017 at 17:48
  • Please share the minimum code that reproduces the problem when you serialize/deserializing a POJO with PropertyName annotations. Commented Jul 26, 2017 at 4:23
  • @FrankvanPuffelen i updated my question with. Is enough? Commented Jul 26, 2017 at 6:19
  • Can you help me with this question please?
    – StuartDTO
    Commented Nov 27, 2017 at 9:33

4 Answers 4

21

The Firebase SDK uses the annotation it finds for the property whenever it gets or sets its value. That means you need to consider how Firebase gets/sets the value, and annotate each place it looks.

Since you're declaring a getter method, Firebase will use that to get the value of the property. It will use the field for setting the value. So the annotation needs to be on both:

public class Pojo {
   @PropertyName("Guid")
   public String guid;

   @PropertyName("Name")
   public String name;

   @PropertyName("Guid")
   public String getPojoGuid() {
       return guid;
   }

   @PropertyName("Guid")
   public void setPojoGuid(String guid) {
       this.guid = guid;
   }
}

If you'd have getters and setters, the annotation would need to be on those, but not on the fields anymore:

public class Pojo {
   private String guid;
   private String name;

   @PropertyName("Guid")
   public String getPojoGuid() {
       return guid;
   }

   @PropertyName("Guid")
   public void setPojoGuid(String value) {
       guid = value;
   }

   @PropertyName("Name")
   public void setPojoGuid(String guid) {
       this.guid = guid;
   }

   @PropertyName("Name")
   public void setPojoGuid(String value) {
       name = value;
   }
}
2
  • 1
    In this case i can use private fields? Commented Jul 26, 2017 at 14:48
  • 1
    Yup. Good point. I updated the code fragment in my answer. Note that you can also just use public fields without getters. I now frequently do this in answer, simply because it's less code to share. Commented Jul 26, 2017 at 14:56
3

What you are looking for is the feature of SDK Version 9.2 in which you can now use a new @PropertyName attribute to specify the name to use when serializing a field from a Java model class to the database. This replaces the @JsonProperty attribute.

@PropertyName("Username")
public String username;
@PropertyName("Email")
public String email;

See also this post in which Frank van Puffelen explains very clearly this concept.

1
  • I use the latest version. I specified in my question that I tried using @PropertyName. Commented Jul 26, 2017 at 12:34
2

@PropertyName :

Marks a field to be renamed when serialized. link

you have to use @PropertyName with public fields and no need for getters/setters

2
  • 1
    Is not working. It update keys with same variable name, like username, not @PropertyName("Username") Commented Jul 25, 2017 at 15:07
  • Can you help me with this question please?
    – StuartDTO
    Commented Nov 27, 2017 at 9:33
0

For Kotlin Data Class

Actually you can annotate the getters and setters of the normal class in java/kotlin but the problem is with data class as there also we have to annotate the members and simple @PropertyName("your-serialized-name") doesn't work as expected.

So lets say you have a data class like this:

data class User(
    val name: String,
    val email: String
) {
    constructor(): this("", "")
}

Now there are two problems:

Problem 1. we cannot annotate the constructor parameterized memeber of data class. Then how we will use annotation ?
Solution: we have to annotate in different way using @get:PropertyName("your-serialized-name) and @set:PropertyName("your-serialized-name)

Problem 2. Now you can see that if you use the setter annotation then you have to make the member of the data class as var instead of val but is this is not what you want as you might want the member as non-mutable.
Solution: I don't have clear idea as this is bug or something else but if we use simple annotation @PropertyName("your-serialized-name") with getter one @PropertyName("your-serialized-name") then both the getter and setter annotation functionality can be achieved.

So in the end your data class should look like this:

data class User(
    @PropertryName("Name")
    @get:PropertryName("Name")
    val name: String,

    @PropertryName("Email")
    @get:PropertryName("Email")
    val email: String
) {
    constructor(): this("", "")
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.