¿Cómo usar la marca de hora del servidor Firebase para generar la fecha creada?

Actualmente, la versión de Google de ServerValue.TIMESTAMP devuelve {".sv":"timestamp"} que se utiliza como directiva para que Firebase llene ese campo con la marca de tiempo del servidor una vez que guarda los datos en el servidor de Firebase.

Sin embargo, cuando crea sus datos en el lado del cliente, no dispone de la marca de tiempo real para reproducir (es decir, utilizarla como fecha de creación). Sólo tendrá acceso a la marca de tiempo después de la inicial guardar y la recuperación consecuente, que – me imagino – es a veces demasiado tarde y no muy elegante.


Antes de Google:

Actualización: ignore esta sección ya que es incorrecta – malentendido los ejemplos. ServerValue.TIMESTAMP devuelve siempre la {".sv":"timestamp"} .

Por lo que he entendido en pre-google Firebase parecía haber una marca de tiempo generada por el servidor disponible que le permitió adquirir la marca de tiempo real:

 import com.firebase.client.ServerValue; ServerValue.TIMESTAMP // eg. 1466094046 

( Ref 1 , ref 2 )


Preguntas:

  1. ¿Es tal salvar / recuperación la única manera de obtener la fecha de creación generada por el servidor en las instancias de mi modelo?
  2. Si es así, ¿puede proponer un método para implementar dicho patrón?
  3. ¿Estoy entendiendo correctamente ServerValue.TIMESTAMP ha cambiado con la adquisición de Google de Firebase? Actualización: No, @FrankvanPuffelen respondió que nada ha cambiado durante la adquisición.

Nota:

No estoy considerando el uso de new Date() en el lado del cliente como he estado leyendo no es seguro, aunque por favor comparta sus pensamientos si usted piensa diferente.

Cuando utiliza la constante ServerValue.TIMESTAMP en una operación de escritura, está diciendo que el servidor de base de datos de Firebase debe determinar la marca de hora correcta cuando ejecuta la operación de escritura.

Digamos que ejecutamos este código:

 ref.addValueEventListener(new ValueEventListener() { public void onDataChange(DataSnapshot dataSnapshot) { System.out.println(dataSnapshot.getValue()); } public void onCancelled(DatabaseError databaseError) { } }); ref.setValue(ServerValue.TIMESTAMP); 

Esto se ejecutará de la siguiente manera:

  1. Adjuntas un oyente
  2. Escribe un valor con ServerValue.TIMESTAMP
  3. El cliente Firebase dispara inmediatamente un evento de valor con una aproximación de la marca de tiempo que escribirá en el servidor
  4. Su código imprime ese valor
  5. La operación de escritura se envía a los servidores Firebase
  6. Los servidores de Firebase determinan la marca de tiempo real y escriben el valor en la base de datos (suponiendo que no se producen fallos en las reglas de seguridad)
  7. El servidor Firebase envía la marca de tiempo real de vuelta al cliente
  8. El cliente Firebase plantea un evento de valor para el valor real
  9. Su código imprime ese valor

Nada cambió en la forma en que generamos ServerValue.TIMESTAMP desde que Firebase se unió a Google. Código que funcionó antes, seguirá funcionando. Eso también significa que la primera respuesta que enlazó es una forma válida de manejarlo.

Lo estoy haciendo un poco diferente.

Solución 1: método push() en POJO

Como no quiero desordenar mis POJOs con extraños getters o propiedades, sólo estoy definiendo un método push() dentro de mis POJOs que se parece a esto:

 /** * Pushes a new instance to the DB. * * @param parentNode `DatabaseReference` to the parent node this object shall be attached to */ fun push(parentNode: DatabaseReference) { parentNode .push() .apply { setValue(this@Pojo) child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP) } } 

Entonces puedo simplemente crear una instancia del POJO y llamar a push() en él que llena correctamente la propiedad del tiempo de creación.

Esto definitivamente hace que el POJO sea un poco menos llano e involucre lógica que un POJO no debería conocer. Sin embargo, el uso de anotaciones y / o lanzamientos @Exclude como se describe en algunas de las respuestas aquí también requiere conocimiento del mecanismo de almacenamiento.

Solución 2: Ayuda o extensión de la DatabaseReference (Kotlin)

Para superar esto, también puedes crear un pushTask(task: Task) en un helper o, si usas Kotlin, un método de extensión para, por ejemplo, DatabaseReference que podría parecerse a esto:

 fun DatabaseReference.push(pojo: Pojo) { push() .apply { setValue(pojo) child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP) } } 

Mirándolo ahora llego a pensar que realmente me gusta el segundo enfoque más ( si tengo Kotlin a mi disposición – no me gustan los ayudantes). Pero esto es probablemente sólo una cuestión de gusto. 😉

  • Java calcular el tiempo entre dos timestamps
  • Constante de fecha y hora de Android SensorEvent
  • Fecha y hora de la fecha
  • ¿String timestamp a Calendario en Java?
  • ¿Cómo obtengo las siguientes marcas de tiempo exactas hasta 5 micro segundos en android
  • Convertir cadena al formato de sello de tiempo de MySQL en php
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.