Experiencing an issue with Firestore returning null instead of data in JavaScript

I have created a form that, upon submission, adds a document with the data to my Firestore database. Additionally, I have set up a real-time listener on the collection where the document is added.

onSubmit={async(e) => {
                        e.preventDefault()
                        const form = document.querySelector(".activityForm")
                        const colRef = collection(db, "inactivity")

                        await addDoc(colRef, {
                            name: user.displayName,
                            from: form.from.value,
                            to: form.to.value,
                            reason: form.reason.value.trim(),
                            reported: serverTimestamp()
                        })
                        .then(() => {
                            console.log("Success!")
                            form.reset()
                        })
                        .catch((err) => {
                            console.log(err)
                        })
                        const q = query(colRef, orderBy("reported", "desc") );
                        
                        const unsubscribe = onSnapshot(q, (querySnapshot) => {
                            setInactiveReps([])
                            querySnapshot.forEach((doc) => {
                                setInactiveReps(prev => {
                                    return [...prev, doc.data()]
                                    })
                            })
                        });
                    }

Subsequently, I am attempting to iterate through and display all the documents in the collection.

                                {inactiveReps && inactiveReps.map(report => (

                                    date = formatDistance(
                                        new Date(report.reported.seconds*1000),
                                        new Date(),
                                        { 
                                          addSuffix: true,
                                          includeSeconds: true
                                        }
                                      ),
                                      console.log(report),

                                    <tr key={report.id} className="h-auto">
                                        <td className="text-white pl-[21px]">{report.name}</td>
                                        <td className="text-white pl-[21px]">{report.from}</td>
                                        <td className="text-white pl-[21px]">{report.to}</td>
                                        <td className="text-white pl-[21px]">{report.reason}</td>
                                        <td className="text-white pl-[21px]">{date}</td>
                                    </tr>
                                ))
                            }

All was running smoothly until the introduction of the real-time listener. Now, an error has emerged stating:

TypeError: can't access property "seconds", report.reported is null
, even though the 'reported' property is clearly not null, as evident when logging the document:

..​.
reported: Object { seconds: 1664099305, nanoseconds: 349000000 }
​...

What could be triggering this issue?

Answer №1

Without testing your specific code, it seems likely that the issue stems from the behavior of serverTimestamp(), which "includes a server-generated timestamp in the written data."

When you call the addDoc() method on the front end, the value of the reported field is not set there because the server/backend handles the setting. However, due to "latency compensation," your listeners will receive updated data before it reaches the backend, leading to report.reported being null.

To ensure that the listener set with onSnapshot() only processes events from the server/back-end, you can use metadata.hasPendingWrites as shown below (code untested):

const unsubscribe = onSnapshot(q, (querySnapshot) => {
    setInactiveReps([])
    querySnapshot.forEach((doc) => {

        if (doc.metadata.hasPendingWrites) {
          // Handle accordingly: skip the doc or mark the timestamp as "pending"
        } else {
            setInactiveReps(prev => {
                     return [...prev, doc.data()]
            })
        }  
    })
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Vue.js to dynamically update input fields based on other field values

I'm a beginner with Vue.js and Vuetify.js, and I am encountering some difficulties with the following: <v-select v-model="car.type" :items="types" label="Type" ></v-select> <div v-if="car.type === 'fiat'"> < ...

Updating DOM elements in AngularJS based on search results and user clicks

I have a query regarding my angular web app, which includes an ajax call for json-formatted dates to display them in a table. The app features a search input, two sorting buttons (for age or name), and a profile sidebar element. I have successfully update ...

A situation arises where the third-party library (react-dev-utils/webpackHotDevClient) is unable to retrieve the necessary data when requiring the 'chalk' object,

Currently, I am operating a react application through the Webpack development server. In my configuration settings, 'react-dev-utils/webpackHotDevClient' is included in the entry array. Unfortunately, this setup results in the following error me ...

Identify modifications in the input and at the same time update another input

I currently have two input text boxes. My goal is to synchronize the content of the second input box whenever the first input box is changed. I attempted to achieve this using this code snippet. However, I encountered an issue where the synchronization on ...

The Next.js function is not operational in the cloud serverless function on Vercel, previously known as Zeit

Struggling to connect with MongoDB hosted on the free tier of atlas? Using nextjs for your API, and attempted to deploy on Vercel (formerly known as Zeit), but encountering issues. Local code runs smoothly, but once deployed to the cloud, it fails to funct ...

Tips for successfully sending an interface to a generic function

Is there a way to pass an interface as a type to a generic function? I anticipate that the generic function will be expanded in the future. Perhaps the current code is not suitable for my problem? This piece of code is being duplicated across multiple fil ...

Filtering options in a dropdown box with jQuery

I have implemented a feature where the content of one select box is filtered based on the option selected in another select box. Below is the code snippet that achieves this functionality: // Filter content based on the selected option in a region select ...

JavaScript combined with a dynamic menu, a customized current link style using CSS, and a site built on PHP

Here's my current website setup: My website is modular and uses dynamic inclusion. The header is a crucial part of the main page, which is responsible for displaying content from specific links on the site. External links to CSS and js files are incl ...

Ways to verify time synchronization in an Ionic 4 application to deter users from manipulating time to cheat or fake

In my Ionic 4 app built with Angular, I am utilizing Firebase through AngularFire to save and retrieve data. The main feature of my app is displaying a list of events from the database that occur within the next two days from the current time. Users also h ...

Guide to export data as Excel (.xlsx) in Next.js

I am in search of a solution to add a button labeled "Download as Excel" to my Nextj application. I have attempted to simplify the development process by using libraries or adding components to my project, but encountered issues with both options: https: ...

Expanding a non-bootstrap navigation bar upon clicking the menu

I'm having some difficulty getting my navigation menu to show up when I click the navigation menu icon. HTML nav role="navigation" class="navbar"> <div class="nav-header"> <a href="#"><span style="font-family: 'Cab ...

Having trouble implementing button functionality in a web app using JS, jQuery, HTML, and CSS along with an API integration

I am currently developing a web search engine that utilizes the Giphy API... However, I've encountered difficulties with the button function. I have created buttons to modify the page format and adjust the number of search results displayed.... The We ...

VueJS - The application is unable to find the designated route

I've encountered an issue with the Signin page in my project. Despite having all other pages functioning properly, the Signin page doesn't seem to render anything when I navigate to it (http://localhost:8080/#/signin). import Vue from 'vu ...

Checking for any lint errors in all JavaScript files within the project package using JSHint

Currently, I am utilizing the gulp task runner to streamline my workflow. My goal is to implement JsHint for static code analysis. However, I have encountered a setback where I can only run one file at a time. Upon npm installation, "gulp-jshint": "~1.11. ...

What is the proper way to utilize the ES6 import feature when using a symbolic path to reference the source file?

I am seeking a deeper understanding of the ES6 import function and could use some assistance. The Situation Imagine that I have a portion of code in my application that is frequently used, so I organize all of it into a folder for convenience. Now, in t ...

Error in JavaScript: Uncaught TypeError - Unable to access the "left" property of an undefined object

This error is really frustrating and I've come across several inquiries regarding this console issue. It's not providing enough information in the chrome console for me to effectively troubleshoot. /** * Adjustment of dropdown menu positio ...

JavaScript - Identifying Repetitive Items in an Array

My goal is difficult to explain in words, but I can show you with code. Here is the array I am working with: var array = [{name:"John",lastname:"Doe"},{name:"Alex",lastname:"Bill"},{name:"John",lastname:"Doe"}] This array has duplicate elements, and I n ...

Configuring Firebase Functions: Setting Up an Optimal Geographical Region

After running a firebase deploy command for a Firebase Function, I noticed that it defaults to ✔ functions[helloWorld(us-central1)]: Successful create operation. I'm wondering where I should specify the region for the function. Below is the code ...

What is the best way to execute JavaScript on the main MVC page when an AJAX request in a partial view has finished?

My Asp.net MVC partial view is designed for searching and makes an Ajax call to retrieve results. After the results are displayed, the user can select a search result by clicking on a link in one of the rows. Upon selecting a search result, an Ajax post re ...

What is the best way to manage numerous asynchronous post requests in AngularJS?

$scope.savekbentry = function (value) { console.log('save clicked'); console.log(value); console.log($scope.kbentry.kbname); $scope.kbentry.mode = value; var kbname = $scope.kbentry.kbname; var kbd ...