Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

289
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!