tutorial studio recuperar realtime query orderbykey how datos java android firebase firebase-database auto-value

java - studio - query firebase android



Cómo usar el valor automático con Firebase 9.2 en Android (2)

Escribí una extensión de AutoValue para esto:

https://github.com/mattlogan/auto-value-firebase

La extensión genera una clase compatible con FirebaseValue , llamada FirebaseValue , como una clase interna estática en tu clase AutoValue generada. Puede convertir su clase AutoValue y su clase FirebaseValue través de los constructores generados.

Aquí hay un ejemplo, copiado del archivo Léame, de cómo se ve eso:

@AutoValue @FirebaseValue public abstract class Taco { public static Taco create(String name, List<Ingredient> ingredients, Review review) { return new AutoValue_Taco(name, ingredients, review); } // Create AutoValue_Taco instance from AutoValue_Taco.FirebaseValue instance public static Taco create(DataSnapshot dataSnapshot) { AutoValue_Taco.FirebaseValue taco = dataSnapshot.getValue(AutoValue_Taco.FirebaseValue.class); return new AutoValue_Taco(taco); } // Create AutoValue_Taco.FirebaseValue instance from AutoValue_Taco instance public Object toFirebaseValue() { return new AutoValue_Taco.FirebaseValue(this); } public abstract String name(); public abstract List<Ingredient> ingredients(); public abstract Review review(); }

Quiero usar el valor automático con firebase 9.2.0+ . Tengo el siguiente código:

@AutoValue public abstract class Office { public static Builder builder() { return new AutoValue_Office.Builder(); } public abstract double latitud(); public abstract double longitud(); @AutoValue.Builder public static abstract class Builder { public abstract Builder latitud(double latitud); public abstract Builder longitud(double longitud); public abstract Office build(); } }

Pero cuando hago para llamar a esta Office office = childDataSnapshot.getValue(Office.class); Estoy recibiendo este error:

com.google.firebase.database.DatabaseException: No properties to serialize found on class com.example.app.model.Office

¿Alguien tiene una idea de por qué estoy recibiendo este error y cómo resolverlo? Leí que firebase ya no usa jackson para la serialización json. Así que no estoy seguro de cómo especificar un tipo de @JsonProperty("latitud") He utilizado @PropertyName sin éxito.

También intenté cambiar el nombre de los métodos abstractos como public abstract double getLatitud(); y después de eso, el error es el siguiente:

java.lang.InstantiationException: Can''t instantiate abstract class com.example.app.model.Office

Entonces no estoy seguro de cómo resolver esto.

SOLUCIÓN

Gracias a hatboysam y Frank van Puffelen finalmente pude enfrentar este problema con la próxima solución.

  1. Creé un enum de FirebaseUtil con dos métodos para serializar y deserializar objetos para Firebase basados ​​en la respuesta de hatboysam y en el comentario de Frank van Puffelen .
  2. Creé un par de clases de User y Phone para probar.
  3. Dependencias:

    compile ''com.fasterxml.jackson.core:jackson-annotations:2.8.0'' compile ''com.fasterxml.jackson.core:jackson-databind:2.8.0''

  4. Ejemplo de uso:

    User user = FirebaseUtil.deserialize(dataSnapshot, User.class); Map<String, Object> map = FirebaseUtil.serialize(user);


No estoy seguro de que esto sea posible con el asignador de datos predeterminado de Firebase, pero existe una posible solución. Primero explique los errores que está viendo:

com.google.firebase.database.DatabaseException: no se han encontrado propiedades para serializar en la clase com.example.app.model.Office

El asignador de Firebase busca ya sea campos public o campos nombrados con el patrón getFoo / setFoo . Entonces, en su clase, el asignador no ve ninguna propiedad.

java.lang.InstantiationException: no se puede crear una instancia de la clase abstracta com.example.app.model.Office

Este es el que creo que tendrás problemas para moverte. Para que la deserialización funcione, su clase necesita tener un constructor público, sin argumentos, que el asignador pueda llamar mediante la reflexión ( newInstance() ). Hasta donde yo sé, esto no es así como funciona AutoValue.

¡Pero no pierdas la esperanza! . De acuerdo con este problema de github hay una manera de hacer que Jackson y AutoValue sean compatibles usando la anotación @JsonCreator . Por lo tanto, deberá usar tanto Jackson como Firebase para realizar el trabajo aquí.

Serialización

// Convert to a Map<String,Object> using Jackson and then pass that to Firebase ObjectMapper mapper = new ObjectMapper(); Map<String, Object> map = mapper.convertValue(office, Map.class); databaseReference.setValue(map);

Deserializando:

// Use Firebase to convert to a Map<String,Object> GenericTypeIndicator<Map<String,Object>> t = new GenericTypeIndicator<Map<String,Object>>() {}; Map<String,Object> map = dataSnap.getValue(t); // Use Jackson to convert from a Map to an Office object ObjectMapper mapper = new ObjectMapper(); Office pojo = mapper.convertValue(map, Office.class);