Each time I attempt to read a single document, Next.js and Firebase consistently encounter serialization errors

Currently, I am in the process of developing a blog website, and most of it is completed except for the functionality of being able to click on a post stub to read the full post. Whenever I try to navigate to the post page, I encounter the following error:

Error: Error serializing .post returned from getServerSideProps in "/posts/[slug]". Reason: undefined cannot be serialized as JSON. Please use null or omit this value.

Despite my efforts to search for a solution, I have been unable to identify the root cause of this issue.

Below is a portion of my Firebase code:

import {
  collection,
  getDocs,
  getFirestore,
  limit,
  onSnapshot,
  orderBy,
  query,
  doc,
  setDoc,
  getDoc,
} from "firebase/firestore";
import firebase from "firebase/app";
import { initializeApp, getApps, getApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
import { Timestamp, toJSON } from "firebase/firestore";
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: "AIzaSyAB4SbXl-I1TMoa31ybnCzmTASXjZFnMAg",
  authDomain: "personal-blog-8decb.firebaseapp.com",
  projectId: "personal-blog-8decb",
  storageBucket: "personal-blog-8decb.appspot.com",
  messagingSenderId: "473768411808",
  appId: "1:473768411808:web:c464d23c531b8bdaa4bfc5",
  measurementId: "G-6F04591W4N",
};

if (!getApps().length) {
  initializeApp(firebaseConfig);
}

const db = getFirestore();

//Reads all the posts in the database
export const getPosts = async () => {
  const q = query(collection(db, "posts"), orderBy("date", "desc"));
  const querySnapShot = await getDocs(q);
  const posts = querySnapShot.docs.map((doc) => ({
    ...doc.data(),
    id: doc.id,
    date: doc.data().date?.toDate().getTime(),
  }));
  return posts;
};

// Get one post from the database based on the slug.
export const getPostBySlug = async (slug) => {
  const docRef = doc(db, "posts", `${slug}`);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    return docSnap.data();
  } else {
    console.log("No Such Document");
  }
};

// Adds posts to the database
export const createPost = async (post) => {
  await setDoc(doc(db, "posts", `${post.slug}`), {
    title: post.title,
    content: post.content,
    date: Timestamp.fromDate(new Date()),
  });
};

export const auth = getAuth();
export const googleAuthProvider = new GoogleAuthProvider();

Furthermore, here is the code for the slug page:

import { async } from "@firebase/util";
import { useRouter } from "next/router";
import { getPostBySlug } from "../../lib/firebase";
import moment from "moment";

export async function getServerSideProps() {
  const post = await getPostBySlug();

  return {
    props: {
      post,
    },
  };
}

export default function PostPage({ post }) {
  <div className="post">
    <h1>{post.title}</h1>
    <span>Published {moment(post.date).format("LL")}</span>
    <p dangerouslySetInnerHTML={{ __html: post.content }}></p>
  </div>;
}

Thank you in advance for any assistance provided.

Answer №1

After making some adjustments, I managed to get it to function correctly. Initially, I modified the firebase read file to utilize a custom query.

// Retrieving a single post from the database based on the slug.
export const getPostBySlug = async (slug) => {
  const q = query(collection(db, "posts"), where("slug", "==", `${slug}`));
  const querySnapShot = await getDocs(q);
  const post = querySnapShot.docs.map((doc) => ({
    ...doc.data(),
    id: doc.id,
    date: doc.data().date?.toDate().getTime(),
  }));
  return post;

I had to take this approach due to the timestamp used with firestore. I couldn't find any other method to properly serialize it to JSON.

Subsequently, I adjusted the getServerSideProps function in the slug js file to accept a context query.

export async function getServerSideProps(context) {
  const post = await getPostBySlug(context.query.slug);
  console.log("this is the severside props: ", post);

  return {
    props: {
      post,
    },
  };
}

Following these changes, everything functioned as expected. There may be more optimal solutions, but this configuration worked effectively in my case.

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

What could be causing my THREE.js Documentation Box to malfunction?

I am a newcomer trying to get the hang of THREE.js. I delved into the THREE.js Documentation and attempted to implement the code, but when I loaded my HTML page, it appeared blank. I am at a loss for what to do next. I utilized Visual Studio Code for codin ...

Differences Between Android and JavaScript: Ensuring Library Validity

Validation in JS is provided by the validator library which can be found at https://www.npmjs.com/package/validator Is there an equivalent library for validation in Android? If so, what is the name of Android's library? ...

Aurelia: Understanding the Integration of a View/ViewModel from an npm Package

We've decided to implement Aurelia for the frontend of our application. With multiple projects in the pipeline, we are looking to streamline the process by packaging our custom code into npm packages that can be easily integrated by developers. This w ...

What is the best way to transfer a JavaScript variable through a query string from one HTML page to another?

Is there a way to pass a JavaScript variable called username from one HTML page, example1.html, to another HTML page, example2.html, using query strings? <script type="text/javascript" > $(document).ready(function() { $('#SubmitForm ...

Displaying JavaScript array contents in an HTML page without using the .innerHTML property

As someone new to the world of JavaScript and web development, I find myself faced with a challenge. I want to showcase the contents of two different JavaScript arrays in an HTML format. However, my research has led me to believe that utilizing .innerHTML ...

Tips for adjusting the icon size within the <IconContext.Provider> dynamically

Currently, I am using the 'IconContext.Provider' tag to style my icons from the 'react-icons' library. Are there any solutions available to dynamically change the size of the icon based on the size of my media? Is using the global styl ...

Quickly redesigning the appearance of file input using javascript and jquery. Seeking assistance to correct css issues on jsfiddle

Hey there, I've been working on styling the input[type="file"] element and could use some assistance. Like the saying goes, "One JSfiddle is worth 1000 words," so here's the link to my example: --- For more details, click here: http://jsfiddle.n ...

Unable to figure out a method to properly synchronize a vue.js asynchronous function

I am facing an issue with my code where everything works fine if I uncomment the "return" statement in fetchData. How can I make sure that I wait for the completion of this.fetchData before populating the items array? I have tried using promises, async/awa ...

Using two distinct buttons to submit information using various methods

When button 1 is clicked, I want it to update the row. When button 2 is clicked, I want it to create another row. This is the controller code for updating: public function update(Request $request, $id){ $pay = Payroll::find($id); $pay ->idnumb ...

React component stuck in endless loop due to Intersection Observer

My goal is to track the visibility of 3 elements and update state each time one of them becomes visible. Despite trying various methods like other libraries, useMemo, useCallback, refs, etc., I still face challenges with my latest code: Endless loop scenar ...

AngularJS - Custom directive to extract a property value from an object

Currently, I am using the following for loop to retrieve the parent category: angular.forEach(queryTicketCategories, function(category) { if(category.id === $scope.ticketCategory.parentId) { $scope.parent = category; } }); I am looking fo ...

Retrieve data from a JSON file URL using a GET request and save the response to be accessed globally when the Vue.js application is initialized

Consider this scenario - I have a Vue.js component where I need to display the name of a user based on their ID. The only information I have is the user's ID. However, I also have a JSON file URL that contains all the user objects with their names and ...

Utilizing Jquery functions within the AngularJS framework

Utilizing Uikit along with its pagination feature, I am attempting to implement this function for changing the page: $('[data-uk-pagination]').on('uk-select-page', function(e, pageIndex){ console.log("page " + pageIndex); ...

Modifying the HTML <select> element with JavaScript

[resolved] I'm encountering an issue with the code below that is supposed to dynamically change the options in a second drop-down menu based on the selection made in the first menu. I've tried to troubleshoot the problem but haven't been suc ...

help a figure leap within the confines of the artwork

Take a look at my jsfiddle here: http://jsfiddle.net/2tLCk/4/ When you press the up button, Mario jumps high into the air and then comes back down. However, if you press it again, he doesn't jump. How can I fix this issue so that when the up button i ...

Retrieve only the initial tag content using jquery

My goal is to extract the "22" from the following code... <div class="left"> <a class="count-link" href="http://url1.com"> <span>22</span> users </a> <a class="count-link" href="http://url2.com"> <span>10</span ...

Opening new windows in Chrome after an AJAX request behaves like a pop-up

When a user clicks a button in my application, an ajax request is triggered. Following the success of this request, I generate a URL which I intend to open in a new tab. Unfortunately, when using Chrome and calling window.open within the success handler, t ...

Seamless changes with graceful fades while transitioning between classes

Is it more efficient to handle this in CSS than using jQuery? I'm not entirely sure. If anyone has a solution, that would be greatly appreciated. However, I am currently facing an issue with the jQuery method I have implemented. It successfully fades ...

What is the best way to add permissions to each role in JavaScript?

I have been attempting to dynamically add data to an HTML table using JavaScript. The data consists of roles and their corresponding permissions, which are retrieved using Laravel's ORM. I have tried utilizing a nested each jQuery function to append t ...

Storing image data using JavaScript

I am in the process of creating a 360-degree viewer that utilizes raster tiles (leaflet) and requires over 85,000 images for each view. In order to enhance the viewer's performance, I am attempting to cache all of these images. However, I keep receivi ...