Al crear un POJO en Firebase, ¿puedes usar ServerValue.TIMESTAMP?

Cuando está creando un Objeto Java Plain Old que se debe serializar y deserializar en Firebase, ¿hay alguna forma de utilizar el valor ServerValue.TIMESTAMP ?

Por ejemplo, supongamos que quiero tener un objeto en el que una de las propiedades sea la última vez que se editó y desee utilizar el valor ServerValue.TIMESTAMP .

En la clase POJO, puede tener:

 private String timeLastChanged; 

o

 private Map timeLastChanged; 

En el primer ejemplo con String , me encuentro con el problema de establecer timeLastChange = ServerValue.TIMESTAMP; , porque ServerValue.TIMESTAMP es un mapa.

En el segundo ejemplo con Map obtengo un error de “error de eliminación de rebote” porque no se puede deserializar adecuadamente el tiempo almacenado en la base de datos en un Map . Hay alguna solución para esto?

Actualización 27/12/2016

Cambié @JsonIgnore por @Exclude como muchos han mencionado.


Finalmente se me ocurrió una solución flexible para trabajar con Dates y ServerValue.TIMESTAMP. Esto funciona a partir de ejemplos de Ivan V , Ossama y puf .

No pude encontrar una manera de lidiar con la conversión entre HashMap , pero si anida la propiedad en un HashMap más genérico HashMap puede ir a la base de datos como una sola longitud value (“date”, “1443765561874”) o como el hash ServerValue.TIMESTAMP (“date”, {“.sv”, “servertime”}). Luego, cuando lo saques, siempre será un HashMap con (“fecha”, “algún número largo”). Luego puede crear un método auxiliar en su clase POJO utilizando la anotación @JsonIgnore @Exclude (lo que significa que Firebase lo ignorará y no lo tratará como un método para serializar a / desde la base de datos) para obtener fácilmente el valor largo del HashMap devuelto a usar en tu aplicación.

El ejemplo completo de una clase POJO está a continuación:

 import com.google.firebase.database.Exclude; import com.firebase.client.ServerValue; import java.util.HashMap; import java.util.Map; public class ExampleObject { private String name; private String owner; private HashMap dateCreated; private HashMap dateLastChanged; /** * Required public constructor */ public ExampleObject() { } public ExampleObject(String name, String owner, HashMap dateCreated) { this.name = name; this.owner = owner; this.dateCreated = dateCreated; //Date last changed will always be set to ServerValue.TIMESTAMP HashMap dateLastChangedObj = new HashMap(); dateLastChangedObj.put("date", ServerValue.TIMESTAMP); this.dateLastChanged = dateLastChangedObj; } public String getName() { return name; } public String getOwner() { return owner; } public HashMap getDateLastChanged() { return dateLastChanged; } public HashMap getDateCreated() { //If there is a dateCreated object already, then return that if (dateCreated != null) { return dateCreated; } //Otherwise make a new object set to ServerValue.TIMESTAMP HashMap dateCreatedObj = new HashMap(); dateCreatedObj.put("date", ServerValue.TIMESTAMP); return dateCreatedObj; } // Use the method described in https://stackoverflow.com/questions/25500138/android-chat-crashes-on-datasnapshot-getvalue-for-timestamp/25512747#25512747 // to get the long values from the date object. @Exclude public long getDateLastChangedLong() { return (long)dateLastChanged.get("date"); } @Exclude public long getDateCreatedLong() { return (long)dateCreated.get("date"); } } 

Quería mejorar la respuesta de Lyla un poco. En primer lugar, me gustaría deshacerme de los métodos public HashMap getDateLastChanged() public HashMap getDateCreated() . Para hacerlo, puede marcar la propiedad @JsonProperty con la anotación @JsonProperty . Otra forma posible de hacerlo es cambiar la detección de propiedades así: @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
En segundo lugar, no entiendo por qué tenemos que poner ServerValue.TIMESTAMP en HashMap mientras que podemos simplemente almacenarlos como propiedad. Entonces mi código final es:

 import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.firebase.client.ServerValue; public class ShoppingList { private String listName; private String owner; @JsonProperty private Object created; public ShoppingList() { } public ShoppingList(String listName, String owner) { this.listName = listName; this.owner = owner; this.created = ServerValue.TIMESTAMP; } public String getListName() { return listName; } public String getOwner() { return owner; } @JsonIgnore public Long getCreatedTimestamp() { if (created instanceof Long) { return (Long) created; } else { return null; } } @Override public String toString() { return listName + " by " + owner; } } 

Esas soluciones me parecen un poco difíciles ya que no sé lo que está haciendo @JsonIgnore. Traté de hacerlo de una manera fácil y parece funcionar.

 private Object dateLastChanged; public Object getDateLastChanged() { return dateLastChanged; } 

Para obtener algo legible por humanos, simplemente paso el valor de retorno dateLastChanged Object en el siguiente método al convertirlo en Long.

 static String convertTime(Long unixtime) { Date dateObject = new Date(unixtime); SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yy hh:mmaa"); return dateFormatter.format(dateObject); } 

Bienvenido a opiniones sobre mi solución ^^

En lugar de usar @JsonIgnore, puedes usar el nativo de Firebase @Exclude . Por ejemplo, trabajo en un proyecto similar y mi modelo es así.

 package com.limte.app.borrador_1.mModel; import com.google.firebase.database.Exclude; import com.google.firebase.database.ServerValue; /** * Created by Familia on 20/12/2016. */ public class ChatItem { String chatName; Long creationDate; public ChatItem() { } public String getChatName() { return chatName; } public void setChatName(String chatName) { this.chatName = chatName; } public java.util.Map getCreationDate() { return ServerValue.TIMESTAMP; } @Exclude public Long getCreationDateLong() { return creationDate; } public void setCreationDate(Long creationDate) { this.creationDate = creationDate; } } 

¡Y este código funciona! En Firebase, los resultados son: Resultados

La misma solución, pero uso esto.

 @IgnoreExtraProperties public class FIRPost { Object timestamp; public FIRPost() { // Default constructor required for calls to DataSnapshot.getValue(FIRPost.class) this.timestamp = ServerValue.TIMESTAMP; } public Object getTimestamp() { return timestamp; } @Exclude public Long getTimestamp(boolean isLong) { if (timestamp instanceof Long) return (Long) timestamp; else return null; } } 

El uso más común para Server.TIMESTAMP es:

  1. establecer el valor del servidor cuando los datos se envían al servidor
  2. trae este modelo de la base de fuego, y ponlo fácilmente en Long

Este truco me ahorró el arduo trabajo de manejar 2 campos diferentes por solo 1 valor

  public class HandleTimestampFirebaseObject { Object timestamp; public HandleTimestampFirebaseObject() { } public Object getTimestamp(){ if(timestamp instanceof Double){ /* this will handle the case of AFTER fetch from backend,and serialize to object into SharedPreferences for example ,when the Object casting automatically into Double. (Anyway,call (long)getTimestamp from your code who use this model*/ return ((Double) timestamp).longValue(); } else{ return timestamp; //this handle to firebase requirement in the server side(Object needed) } }