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? 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? 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;
   }
}
Sign up to request clarification or add additional context in comments.

2 Comments

In this case i can use private fields?
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.
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 Comment

I use the latest version. I specified in my question that I tried using @PropertyName.
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 Comments

Is not working. It update keys with same variable name, like username, not @PropertyName("Username")
Can you help me with this question please?
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("", "")
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.