es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

firebase.serverTimestamp() tiene un retraso (con JavaScript básico).

Estoy tratando de crear un chat en vivo con vanilla JS y Firebase.
Puedo agregar y obtener el mensaje más “nuevo” para renderizar en el DOM con los siguientes códigos:

Añadir mensaje

  async addChat(message) {
    const chat = {
      message,
      createdAt: serverTimestamp(),
    };

    return await addDoc(this.chat, chat);
  }

Obtener mensaje

  getChat(syncChat) {
    onSnapshot(this.chat, snapshot => {
      snapshot.docChanges().forEach(shot => {
        if (shot.type === "added") {
          syncChat(shot.doc.data());
        }
      });
    });
  }

Renderizar mensaje en el DOM

  render(data) {
    const html = `
      <li class="chat-item">
      <span class="chat-message">${data.message}</span>
      <p class="chat-time">${formatDistanceToNow(data.createdAt.toDate(), {
        addSuffix: true,
      })}</p>
      </li>
    `;

    this.chatList.innerHTML += html;
  }

Como dije, puedo renderizar el mensaje del chat sin problema, pero me di cuenta de que hay un retraso cuando se agrega el mensaje a Firebase y se crea la marca de tiempo. Entonces, cuando se muestra el primer mensaje nuevo en el DOM, el tiempo en realidad aparece como “null” y tengo que actualizar la página para mostrar el tiempo correcto.

Solo quería saber si hay alguna manera de solucionar eso. Intenté consultar la documentación de Firebase y no encontré nada. También investigué un poco en Internet, pero la mayoría de los ejemplos utilizaban un framework y no vanilla JS.

Gracias por la ayuda.

SOLUCIÓN

  getChat(showChat) {
    const q = query(
      this.collection,
      where("room", "==", this.room),
      orderBy("createdAt", "asc")
    );
    this.unsub = onSnapshot(q, snapshot => {
      snapshot.docChanges().forEach(snap => {
        if (snap.type === "added") {
          showChat(snap.doc.data({ serverTimestamps: "estimate" }));
        }
      });
    });
  }

Gracias por la ayuda. He decidido utilizar la opción snapshotoptions, el servidor de tiempo estimado y todo funciona muy bien.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para solucionar el problema de retraso en el tiempo cuando se agrega un mensaje a Firebase y se crea la marca de tiempo, puedes utilizar la opción serverTimestamps en tu escuchador onSnapshot.

    En tu función getChat, modifica el código para incluir la opción serverTimestamps:

    getChat(syncChat) {
      onSnapshot(this.chat, { serverTimestamps: 'estimate' }, snapshot => {
        snapshot.docChanges().forEach(shot => {
          if (shot.type === "added") {
            syncChat(shot.doc.data());
          }
        });
      });
    }
    

    Al establecer serverTimestamps en 'estimate', Firebase estimará la marca de tiempo del servidor si no se puede garantizar una precisión completa debido a la latencia de la red u otros factores.

    Con esta modificación, el primer nuevo mensaje mostrado en el DOM seguirá mostrando una marca de tiempo (aunque estimada) y no será necesario actualizar la página para mostrar la hora real.

Comments are closed.