Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

296
Vistas
firebase severtimestamp delay (w/ vanilla JS)

I am trying to create a live chat with vanilla JS and firebase. I'm able to add and get the "newest" message render to the DOM with the following codes:

add message

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

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

get message

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

render message to the 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;
  }

Like I said, I can render the chat message no problem, but I realize the there's a time delay when message is added to firebase and timestamp is created. So when the first new message is displayed on the DOM, the time actually return null, and I have to refresh the page in order to display the actually time.

I am just wondering if there's anyway to fix that? I tried looking through the firebase doc and got nothing. I also did a little bit of digging on the interest but most of them are using a framework and not vanilla js.

Thanks for the help.

SOLUTION

  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" }));
        }
      });
    });
  }

Thanks for the help! I have decide to use the snapshotoptions, the estimate servertimestamps, and everything works great.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

When you perform a write operation on a client, the Firestore SDK immediately invoked all local listeners with the new data - something typically referred to as latency compensation within Firebase.

So when you write a new document with a server-side timestamp, your onSnapshot listener gets called before the request is sent to the server, and at that point the value of the timestamp field will be null, since it hasn't been calculated yet.

Then when the server confirms that the write operation was completed, and what the timestamp value was, your onSnapshot listener gets called again, now with the correct value for the timestamp field. Since this is a change to the document you already got before, it is an event with type changed.

To display the update, your code needs to also handle events where the type is changed, and use that to update the DOM element that it added for the first event.

Alternatively you can ask the Firestore SDK to give you an estimated timestamp on the first event by passing an option to the data() call as shown here: Firebase Cloud Firestore how to set snapShotOptions

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda