fireship-io / next-firebase-course

Next.js + Firebase - The Full Course
next-firebase-course-git-main.fireship.vercel.app
477 stars 218 forks source link

Error: A required parameter (username) was not provided as a string in getStaticPaths for /[username]/[slug] #27

Open Vilod opened 1 year ago

Vilod commented 1 year ago

Error: A required parameter (username) was not provided as a string in getStaticPaths for /[username]/[slug] How do I fix this issue?

Abdessamad-Y commented 1 year ago

I haded the same problem but when I console .log I found undefind in username and slug so I restarted firebase created a new data base and it worked try it out and let me know

Vilod commented 1 year ago

Could you explain in a more detailed way, please?

Abdessamad-Y commented 1 year ago

yes sure when I console.log(paths) I found undefined values attributed to slug and username which caused the problem somehow so I deleted the firebase database then rerun the code and allowed to create the database again so the solutions are two either delete your database from firebase or try this code : params: { slug : slug || null, username : username || null },

this was one of the error that gave me the idea while trying to fix it:

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

Vilod commented 1 year ago

Could you please send the full [username]/[slug].js code?

Abdessamad-Y commented 1 year ago
export async function getStaticPaths() {
  const snapshot = await firestore.collectionGroup('posts').get();
  const paths = snapshot.docs.map((doc) => {
    const { slug, username } = doc.data();
    console.log(doc.data())
    return {
       params: { slug : slug || null, username : username || null },
    };
  });
  return {
    paths,
    fallback: 'blocking',
  };
}
Vilod commented 1 year ago

`import styles from '@styles/Post.module.css'; import PostContent from '@components/PostContent'; import HeartButton from '@components/HeartButton'; import AuthCheck from '@components/AuthCheck'; import Metatags from '@components/Metatags'; import { UserContext } from '@lib/context'; import { firestore, getUserWithUsername, postToJSON } from '@lib/firebase'; import { doc, getDocs, getDoc, collectionGroup, query, limit, getFirestore } from 'firebase/firestore'; import firebase from 'firebase/app'; import 'firebase/firestore';

import Link from 'next/link'; import { useDocumentData } from 'react-firebase-hooks/firestore'; import { useContext } from 'react';

export async function getStaticProps({ params }) { const { username, slug } = params; const userDoc = await getUserWithUsername(username);

let post; let path;

if (userDoc) { // const postRef = userDoc.ref.collection('posts').doc(slug); const postRef = doc(getFirestore(), userDoc.ref.path, 'posts', slug);

// post = postToJSON(await postRef.get());
post = postToJSON(await getDoc(postRef) );

path = postRef.path;

}

return { props: { post, path }, revalidate: 100, }; } export async function getStaticPaths() { const snapshot = await firestore.collectionGroup('posts').get(); const paths = snapshot.docs.map((doc) => { const { slug, username } = doc.data(); console.log(doc.data()) return { params: { slug : slug || null, username : username || null }, }; }); return { paths, fallback: 'blocking', }; }

export default function Post(props) { const postRef = doc(getFirestore(), props.path); const [realtimePost] = useDocumentData(postRef);

const post = realtimePost || props.post;

const { user: currentUser } = useContext(UserContext);

return (

); }` This is my code but it doesn't work

matthall1998 commented 1 year ago

I just had the same issue, what solved it for me...

Make sure in your subcollection (posts), the document name needs to match the slug value.

Solved it for me!

Again you have.... users -> 'UID' -> posts -> 'DOCNAMEHERE'

'DOCNAMEHERE' needs to be the same as the 'slug' field. 👍