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

The AWS API Gateway quickly times out when utilizing child_process within Lambda functions

I'm encountering an issue with my Lambda function being called through API Gateway. Whenever the Lambda triggers a spawn call on a child_process object, the API Gateway immediately returns a 504 timeout error. Despite having set the API gateway timeou ...

Add a fresh category to a JSON document

Combining Express (Node.js) and Mongoose, I am developing a REST API and attempting to implement JWT token-based login. However, I have encountered an issue. Upon executing the code below: const mongoose = require('mongoose'); const User = mongo ...

Javascript issue: opening mail client causes page to lose focus

Looking for a solution! I'm dealing with an iPad app that runs html5 pages... one specific page requires an email to be sent which triggers the Mail program using this code var mailLink = 'mailto:' + recipientEmail +'?subject=PDFs ...

What is the best method for activating a function with @click within an infowindow on Google Maps in Vue.js?

Here's the current code snippet: addpolygon: function(e) { var vm = this; var point = { lat: parseFloat(e.latLng.lat()), lng: parseFloat(e.latLng.lng()) }; vm.coord.push(point); vm.replot(); vm.mark ...

Uploading files with Vue.js Element-UI and axios triggers unwanted page refresh

I am utilizing the element-ui file upload component() to manage the frontend of image uploading. All functionalities work flawlessly (file is successfully sent to the server, etc). However, for some reason, after the axios's successful response code r ...

Utilizing React JS to Activate the Glyphicon Calendar Icon on Click

Could someone please advise on how to make the calendar glyphicon activate the datetime picker upon clicking? I have a button currently but it is not functional. I've been searching for React-specific solutions without success. <div className={cla ...

Styling Links in NextJS with styled-components seems to be challenging

Every time I try to insert a styled anchor element within the Link component, I keep encountering the 'Hydration failed' error. Despite looking for solutions on various forums, simply adding the passHref property to Link doesn't seem to reso ...

Having trouble accessing functions in Typescript when importing JavaScript files, although able to access them in HTML

Recently, I started incorporating TypeScript and React into my company's existing JavaScript code base. It has been a bit of a rollercoaster ride, as I'm sure many can relate to. After conquering major obstacles such as setting up webpack correc ...

leaving code block using Express and Node

My code is displayed below: // Implement the following operations on routes ending with "users" router.route('/users') .post(function(req, res, next) { var user = new User(); user.username = req.body.username; user.p ...

Execute a function prior to making a synchronous call

Seeking guidance on a complex issue that I have encountered. In my code, I am dealing with a synchronous AJAX call and need to execute a function before this particular call is made. The function in question is a simple one: $.blockUI(); This function ...

Unusual issue in IE causing rendering problems in reporting services

Currently, I am creating a report using Reporting Services 2008, MVC 2, and Ajax as my development technologies. When I generate the report, everything displays perfectly if there is data present. However, if there is no data, the report body gets cut off ...

How can I dynamically update the status displayed in a DIV tag using PHP code?

I'm working on a web page where I am downloading data one by one in a continuous loop. Once each download is complete, I need to update the status displayed in a DIV tag on the webpage. The server connection and data download are handled by PHP code, ...

Unable to delete a dynamically inserted <select> element by using the removeChild method

As someone who is new to coding web applications, I am currently working on a project that involves adding and deleting dropdowns dynamically. Unfortunately, I have run into an issue where the delete function does not work when the button is pressed. Her ...

The JavaScript code snippets are ineffective, yielding an error message of "resource failed to load."

<? echo '<html> <script language=javascript> function validate() { alert("validate"); document.form1.action="validate.php"; document.form1.submit(); return false; } function del() { alert("delete"); document.form ...

Troubleshooting issue with JavaScript sorting function failing to arrange elements in ascending

I'm having trouble sorting numbers in ascending order using JavaScript. Here's the code snippet: <h2>JavaScript Array Sort</h2> <p>Click the button to sort the array in ascending order.</p> <button onclick="myFunctio ...

Tips for breaking up array elements across multiple "tr" tags

In this particular example, I have a Fiddle set up with multiple tr elements displayed within an ng-repeat. My goal is to have three td elements per row. Would it be necessary to use an inner angularjs ng-repeat and split the iconDets array for this purpos ...

The header that sticks on scroll is annoyingly blocking the content

I managed to create a sticky on-scroll header/navigation bar successfully. Here is how it looks now However, I encountered an issue. When it reaches the top, it automatically 'covers' the top part of my content, which has text on it, and I don& ...

What is the process for including a new item in the p-breadcrumb list?

Having trouble getting my code to add a new item to the p-breadcrumb list on click. Any assistance would be greatly appreciated. Thank you in advance! Check out the live demo here ngOnInit() { this.items = [ {label: 'Computer'}, ...

Issue with locating .env file in GitHub CI Docker environment

Looking to deploy my Next.JS app using Docker and GitHub CI. The actions are running as expected, but I'm facing an issue with the .env.production file not being found when referenced in the Dockerfile. I attempted renaming the file to .env or other ...

Initiate an Ajax request from a hyperlink

Is it possible to trigger an Ajax request from a hyperlink? I am interested in updating the inner html of a div element upon clicking on a hyperlink through JavaScript. ...