繁体   English   中英

Firebase/NextJS:无法访问动态路由的子集合

[英]Firebase/NextJS: Can't access subcollections for dynamic routing

我正在构建一个故事编辑器,您可以在其中编写故事并将它们分成不同的章节,并且我无法访问 NextJS 的“getStaticPaths”的子集合,因为每个文档都是一个 UUID。

我将数据存储在 Firebase Firestore 中,如下所示:

stories
├── UUID1 (Story 1)
│    └──chapters
│        └── UUID (Chapter 1)
│        └── UUID (Chapter 2)
│
│  
├── UUID2 (Story 1)
│    └──chapters
│        └── UUID (Chapter 1)
│        └── UUID (Chapter 2)
│   

问题

我无法访问章节子集,因为我无法获取 UUID。

通常,为了访问这些章节,我创建了一个 useEffect 挂钩来将 UUID 存储到 useState 挂钩中,这样我就可以像下面的代码一样发送查询:

const chaptersQ = query(
      collection(db, "stories", story.data().id, "chapters")
    );

不幸的是,在尝试创建动态路由时,“getStaticPaths”存在于主要 function 之前/之外,因此我无法使用反应钩子。

这是我当前的代码:

export const getStaticPaths = async () => {
  const storyQ = collection(db, "stories");
  const queryStory = await getDocs(storyQ);

  queryStory.forEach(async (story) => {
    const chaptersQ = query(
      collection(db, "stories", story.data().id, "chapters")
    );
    const queryChapters = getDocs(chaptersQ);

    return {
      paths: (await queryChapters).docs?.map((doc) => ({
        params: {
          id: `${doc.data().storyID}`,
          chapter: `${doc.data().chapter}`,
        },
      })),
    };
  });
};

这将返回一个无效错误,因为路径以某种方式收到未定义的错误。

我花了几个小时来研究这个。 我得到的最接近的方法是在文件的根层中声明一个带有“let”的变量,然后将 chapter doc.data 推入其中。

然后在返回语句中使用它来设置路径和参数。 但是,这也返回了未定义的错误。

先感谢您!

forEach方法不返回值,因此不会正确设置paths属性,这意味着它将是未定义的。

在我看来,有两种方法可以获得所需的结果:

  1. 您可以使用map function 而不是forEach来创建路径数组,然后返回它。
export const getStaticPaths = async () => {
  const storyQ = collection(db, "stories");
  const queryStory = await getDocs(storyQ);

  const paths = await Promise.all(queryStory.map(async (story) => {
    const chaptersQ = query(
      collection(db, "stories", story.data().id, "chapters")
    );
    const queryChapters = await getDocs(chaptersQ);

    return queryChapters.docs.map((doc) => ({
      params: {
        id: `${doc.data().storyID}`,
        chapter: `${doc.data().chapter}`,
      },
    }));
  }));

  return {
    paths: paths.flat(),
  };
};

这应该正确创建路径数组,但您可能需要根据您的特定用例对其进行调整。

  1. 使用 async/await 并创建一个空数组,然后将路径推送到其中。
export const getStaticPaths = async () => {
  const storyQ = collection(db, "stories");
  const queryStory = await getDocs(storyQ);

  let paths = []
  for (const story of queryStory) {
    const chaptersQ = query(
      collection(db, "stories", story.data().id, "chapters")
    );
    const queryChapters = await getDocs(chaptersQ);

    for(const chapter of queryChapters.docs) {
      paths.push({
        params: {
          id: `${chapter.data().storyID}`,
          chapter: `${chapter.data().chapter}`,
        },
      });
    }
  }
  return {
    paths,
  };
};

如果让我选择使用哪种方法,我会选择第一种。 由于Promise.all()给出了干净的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM