¿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.
- Insertar una marca de tiempo en la base de datos a través de ContentValues
- ¿Cómo obtener la hora actual del servidor firebase en milisegundos?
- Android - Cómo marcar marcas de tiempo en un SeekBar
- Error de VideoView getCurrentPosition () en Acer Iconia A200
- ¿Se convierte la cadena de fecha en timestamp en Android?
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:
- ¿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?
- Si es así, ¿puede proponer un método para implementar dicho patrón?
- ¿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.
- Android: obtenga la hora de la fecha de la marca de tiempo de SMS en milisegundos
- ¿Cómo comparar dos marcas de tiempo en android?
- Para obtener la fecha y la hora de Timestamp Android
- Conversión de la marca de hora como cadena a la fecha en android
- ¿Android consigue el timestamp actual?
- La fecha y hora muestran datos erróneos
- Obtener una marca de tiempo larga del selector de fechas onDateSet
- Convertir timestamp en fecha actual en android
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:
- Adjuntas un oyente
- Escribe un valor con
ServerValue.TIMESTAMP
- El cliente Firebase dispara inmediatamente un evento de valor con una aproximación de la marca de tiempo que escribirá en el servidor
- Su código imprime ese valor
- La operación de escritura se envía a los servidores Firebase
- 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)
- El servidor Firebase envía la marca de tiempo real de vuelta al cliente
- El cliente Firebase plantea un evento de valor para el valor real
- 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. 😉
- SQLite – ¿Es posible insertar un BLOB a través de la instrucción insert?
- Lista de solicitudes HTTP desde el teléfono Android