Firebase No properties to serialize found on class - java

I'm bloqued creating a Firebase Database.
I'm trying to model a class. A very simple class:
package com.glups.model;
import com.google.firebase.database.IgnoreExtraProperties;
#IgnoreExtraProperties
public class AlumnoFB {
private String nombre;
private String apellidos;
private String telefono;
private String email;
private Boolean tieneWhatsapp;
private Boolean tieneTelegram;
private Boolean tieneHangouts;
private Long formaPago;
private Double ratioHora;
private Double precioHora;
private Double horasCompensadas;
public AlumnoFB() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public AlumnoFB(String nombre,
String apellidos,
String telefono,
String email,
Boolean tieneWhatsapp,
Boolean tieneTelegram,
Boolean tieneHangouts,
Long formaPago,
Double ratioHora,
Double precioHora,
Double horasCompensadas) {
this.nombre = nombre;
this.apellidos = apellidos;
this.telefono = telefono;
this.email = email;
this.tieneWhatsapp = tieneWhatsapp;
this.tieneTelegram = tieneTelegram;
this.tieneHangouts = tieneHangouts;
this.formaPago = formaPago;
this.ratioHora = ratioHora;
this.precioHora = precioHora;
this.horasCompensadas = horasCompensadas;
}
}
that is almost like a sample class from Firebase.
Application user obtained from getUser() has been logged on Firebase.
When I call SetValue:
AlumnoFB alumno = new AlumnoFB("", "", "", "", false, false, false, ((Integer)FormaPago.INT_NO_PAGADO).longValue(), 0.0, 0.0, 0.0);
mDatabase.child("AlumnoFB").child(ControlClasesFirebase.getUser().getUid()).setValue(alumno) ;
A fatal exception raises.
06-10 10:17:37.179 13841-13841/com.glups.controlclases E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.glups.controlclases, PID: 13841 com.google.firebase.database.DatabaseException: No properties to serialize found on class com.glups.model.AlumnoFB
at com.google.android.gms.internal.zzaix$zza.<init>(Unknown Source)
at com.google.android.gms.internal.zzaix.zzj(Unknown Source)
at com.google.android.gms.internal.zzaix.zzaw(Unknown Source)
at com.google.android.gms.internal.zzaix.zzav(Unknown Source)
at com.google.firebase.database.DatabaseReference.zza(Unknown Source)
at com.google.firebase.database.DatabaseReference.setValue(Unknown Source)
at com.glups.controlclases.MainActivity$4.onClick(MainActivity.java:305)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5258)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I've checked types, and all are accepted. What's wrong?

Firebase require your Pojo to have public variables or getter/setter.
Change variable declarations to public
public String nombre;
public String apellidos;
public String telefono;
public String email;
public Boolean tieneWhatsapp;
public Boolean tieneTelegram;
public Boolean tieneHangouts;
public Long formaPago;
public Double ratioHora;
public Double precioHora;
public Double horasCompensadas;

If you are using proguard, some methods in the model could be stripped out depending on your configuration. As we know that there is no much optimization to POJO as it has only fields with getters and/or (optionally) setters, you can use the annotation "#Keep" so proguard will not delete any methods from this class.
Check this for more info: https://developer.android.com/studio/build/shrink-code.html
#Keep
public class Store {}

In my case I forgot to add a proguard rule to keep the model classes:
-keep class com.google.firebase.example.fireeats.model.** { *; }
This is same as #aselims's answer, just proguard version.
I found it in the official firestore example:
https://github.com/firebase/quickstart-android/blob/master/firestore/app/proguard-rules.pro

I have got this issue today and just resolve this providing getter/setter for private variables.
ex:
private String pid;
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
Now it's work perfectly without any error. Hope it will help newbies devs.

SOLUTION
In my case the issue was only in release/signed mode APK. So I fixed by doing these steps..
1- Added all model classes into proguaed rules like
-keep class com.YOUR_PACKAGE_NAME.modelClass.** { *; }
OR
#Keep
public class modelClass {}
2- Declared all variables of model class as private
3- Removed conflicting keys
Chill Pill :)

Verify this:
buildTypes {
release {
minifyEnabled false
...
}
debug {
minifyEnabled false
...
}
}

Declare variables as public.
public String email

In case anyone runs into this and none of the above solutions work, the variables declared also need to be of Object type and not raw types.
For example, you can use Integer's but you cannot use int's.
Same is true for boolean, float, double, etc. Basically, any unboxed type.

adding
#ServerTimeStamp
public Date date;
helped me to resolve the issue

You can do either of the two things -
Make your variables public
OR
Add getters and setters for all the variables

To solve the issue as mentionned below you should declare the class as Serializable and for the code :
`data class Review(
var rating:Float=0f,
var userId:String="",
var textR:String="",
#ServerTimestamp var timestamp: Date? = null
):Serializable{
constructor( rating: Float,userId: String, text: String):this() {
this.userId = userId
this.rating = rating
this.textR = text
}
}`

Try This Solution!
1- Implement Serializable interface
class model implements Serializable {}
2- Class Model with Private properties with Constructor and public setter and getter methods
public class Message implements Serializable {
#ServerTimestamp
private Date created;
private String content;
private String from;
private String to;
public Message(Date created, String content, String from, String to) {
this.created = created;
this.content = content;
this.from = from;
this.to = to;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
}
3- add this code in Proguard rules as said here
# Add this global rule
-keepattributes Signature
# This rule will properly ProGuard all the model classes in
# the package com.yourcompany.models.
# Modify this rule to fit the structure of your app.
-keepclassmembers class com.yourcompany.models.** {
*;
}

Related

Entity class defines non-transient non-serializable instance field price

Below little bit of code showing SONAR bug like :Class com.sample.Submit defines non-transient non-serializable instance field price. How can we get rid from this issue.
Code
#JsonIgnoreProperties(ignoreUnknown = true)
public class Submit implements Serializable {
/**
* serialVersionUID of type long.
*/
private static final long serialVersionUID = 0L;
#JsonProperty("billCode")
private String billCode;
#JsonProperty("displayName")
private String displayName;
#JsonProperty("visible")
private Boolean visible;
#JsonProperty("price")
private Price price;
public Boolean getVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public String getBillCode() {
return billCode;
}
public void setBillCode(String billCode) {
this.billCode = billCode;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public Price getPrice() {
return price;
}
public void setPrice(Price price) {
this.price = price;
}
}
Declare your class Price serializable as follows:
public class Price implements Serializable {
...
}
If you actually need the class to be serializable, then every one of its instance members, like Price, needs to be serializable as well.
Consider if you actually need this Submit class to be serializable though. If you are not doing anything that requires storing this or copying it across a network (like putting it in the HTTP session, or saving it on a file system, or putting it in a queue), you may not need the class to be serializable at all, in which the best course to take is to delete the implements Serializable from the Submit class.
(Be aware that making the class serializable has nothing to do with using it to generate JSON.)

How to find differences between two collections

I have following DTOs:
#Data
public class PersonDTO implements Diffable<PersonDTO> {
private String id;
private String firstName;
private String lastName;
private List<AddressDTO> addresses;
#Override
public DiffResult diff(PersonDTO personDTO) {
return new DiffBuilder(this, personDTO, SHORT_PREFIX_STYLE)
.append("id", this.id, personDTO.getId())
.append("firstName", this.firstName, personDTO.getFirstName())
.append("lastName", this.lastName, personDTO.getLastName())
.append("addresses", addresses, personDTO.getAddresses())
.build();
}
}
#Data
public class AddressDTO implements Diffable<AddressDTO> {
private String id;
private String personId;
private String addressType;
private String street;
private String houseNumber;
private String postalCode;
private String city;
private String countryId;
#Override
public DiffResult diff(AddressDTO addressDTO) {
return new DiffBuilder(this, addressDTO, SHORT_PREFIX_STYLE)
.append("id", this.id, addressDTO.getId())
.append("personId", this.personId, addressDTO.getPersonId())
.append("addressType", this.addressType, addressDTO.getAddressType())
.append("street", this.street, addressDTO.getStreet())
.append("houseNumber", this.houseNumber, addressDTO.getHouseNumber())
.append("postalCode", this.postalCode, addressDTO.getPostalCode())
.append("city", this.city, addressDTO.getCity())
.append("countryId", this.countryId, addressDTO.getCountryId())
.build();
}
}
My main goal is to find differences between two similar person objects. Currently I've tried to use Diffable interface from apache commons which is perfectly good for object. Please advise how to deal with collections when size of each collection can be different. For instance few addresses were removed, few was added and few was updated. Please see example below:
Probably there is another library which helps to achieve similar goals, please advice
source can be your first object
target can be your second object
Iterator targetIt = target.iterator();
for (Object obj:source)
if (!obj.equals(targetIt.next())
// Element has changed

Class has two properties of the same name. Why does this happen?

I implemented a Java web service (JAX-RS API Jersey implementation). There is an entity:
#XmlRootElement
public class TestPhoto extends Photo {
public enum Type {
BEFORE, AFTER, ADDON
}
private User author;
#XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
private LocalDateTime createdTime;
private Type type;
public TestPhoto() {
super();
}
public TestPhoto(Long id, String key, String path, User author, LocalDateTime createdTime, Type type) {
super(id, key, path);
this.author = author;
this.createdTime = createdTime;
this.type = type;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public LocalDateTime getCreatedTime() {
return createdTime;
}
public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
}
When I am trying to retrieve a list of such entities, I get an error:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExceptions
Class has two properties of the same name "createdTime"
this problem is related to the following location:
at public java.time.LocalDateTime com.test.TestPhoto.getCreatedTime()
at com.test.TestPhoto
at public java.util.List com.test.TestAccount.getAddonPhotos()
at com.test.TestAccount
this problem is related to the following location:
at private java.time.LocalDateTime com.test.TestPhoto.createdTime
at com.test.TestPhoto
at public java.util.List com.test.TestAccount.getAddonPhotos()
at com.test.TestAccount
I know how to fix this. For instance, I could rename private fields and add _ as a prefix. Or I could add a #XmlAccessorType(XmlAccessType.FIELD) annotation to a field.
I see also, that there is something wrong with #XmlJavaTypeAdapter(LocalDateTimeAdapter.class) annotation. If comment it out everything works fine. But that part of functionality won't work in this case.
What I am trying to understand is why this happened in the first place. The code worked perfectly fine and then just stopped and started throwing such exceptions. Should this code have worked in the first place? Or is it completely wrong?

JAX-RS/Jersey: java.lang.ClassCastException - cannot be cast to javax.xml.bind.JAXBElement

I have application separated to frontend and backend modules which communicate through restfull webservice. Unfortunately, something goes wrong in this code and I get from Backend part:
java.lang.ClassCastException: com.rrd.ecomdd.data.SharedFile cannot be cast to javax.xml.bind.JAXBElement
Frontend snippet:
#Override
public void share(Set<SharedFile> fileSet) {
apiTarget.path(ApiConstant.FILESERVICE)
.path(ApiConstant.FILESERVICE_SHARE)
.request(MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8"))
.post(Entity.entity(fileSet.toArray(new SharedFile[0]), MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8")), new GenericType<Set<SharedFile>>() {
});
}
Backend snippet
#POST
#Path(ApiConstant.FILESERVICE_SHARE)
#Produces("application/json; charset=UTF-8")
#Consumes("application/json; charset=UTF-8")
public List<SharedFile> share(SharedFile[] sharedList) {
for (SharedFile s : sharedList) {
fileService.share(s);
}
return Arrays.asList(sharedList);
}
SharedFile class:
public class SharedFile {
private Long id;
private User user;
private ManagedFile file;
private UUID uuid = UUID.randomUUID();
public SharedFile(User user, ManagedFile file) {
this.user = user;
this.file = file;
}
public SharedFile() {
}
//getters, setters, equals and hashcode below
}
Any ideas how to fix this?
Try to annotate the class and its attributes as mentioned here:
#XmlRootElement
public class SharedFile {
#XmlElement
private Long id;
#XmlElement
private User user;
#XmlElement
private ManagedFile file;
Follow this for more: http://docs.oracle.com/javaee/6/tutorial/doc/gkknj.html

How to refer to an inner class inside a list in Java

after messing around with parsing a JSON response with GSON for a day, I finally figured out how to get my javabeans right in order to extract my data from the response. This is the layout of my nested classes and lists:
public class LocationContainer {
public class paging {
private String previous;
private String next;
}
private List<Datas> data;
public class Datas {
private String message;
private String id;
private String created_time;
public class Tags {
private List<Data> datas;
public class Data {
private String id;
private String name;
}
}
public class Application {
private String id;
private String name;
}
public class From {
private String id;
private String name;
}
public class Place {
private String id;
private String name;
public class Location {
private int longitude;
private int latitude;
}
}
}
}
Now I am trying to get a hold of the name string inside the place class and the created_time string, but since I am quite a noob, I can't seem to figure it out.
I was able to extract the created_time string by using
String time = gson.toJson(item.data.get(1).created_time);
However using
String name = gson.toJson(item.data.get(1).Place.name);
doesnt work.
The item class is an instance of LocationContainer filled with the output from GSON.
Any pointers would be greatly appreciated.
created_time is a member variable of Data, so your first line is fine.
However, Place is not a member variable, it's just a class definition. You probably need to instantiate a member variable inside your Data class, e.g.:
private Place place;

Categories

Resources