为什么我的Next.js页面在第一次加载时没有加载数据并抛出“FirebaseError:无效文档引用”错误?

s5a0g9ez  于 2023-03-12  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在使用nextauth记录注册到我的平台的用户的帐户/会话。我在下面的app\user[id]\page.js下有一个用户 Jmeter 板,其中Id是doc.id使用我的[... nextauth] API文件中的firestoreAdapter从nextauth登录到firestore的www.example.com。

"use client";
import { useState, useEffect } from "react";
import { db } from "@/lib/firebaseConfig";
import { getDoc, doc } from "firebase/firestore";

function User() {
  const pathname = window?.location.pathname;
  const userId = pathname.substring(6);
  const [user, setUser] = useState({});

  useEffect(() => {
    const getUser = async () => {
      const docRef = doc(db, "users", userId);
      const docSnap = await getDoc(docRef);
      if (docSnap.exists()) {
        setUser(docSnap.data());
      } else {
        console.log("No such document!");
      }
    };
    getUser();
  }, []);

  return (
    <div>
      <h1 className="text-white">{userId}</h1>
      <img src={user.image} />
    </div>
  );
}

export default User;

我的意图是在页面加载后立即获取上述数据,现在,只有当我重新加载页面时才会加载数据,而不是在第一次加载时。
在终端上,我收到以下错误:

error - app\user\[id]\page.js (7:19) @ window
error - ReferenceError: window is not defined
    at User (./app/user/[id]/page.js:16:22)
   5 | 
   6 | function User() {
>  7 |   const pathname = window?.location.pathname;
     |                   ^

在浏览器中,我得到以下错误:

Unhandled Runtime Error
FirebaseError: Invalid document reference. Document references must have an even number of segments, but users has 1.

我认为问题是因为useEffect在客户端渲染之前就开始了。新手问题,但是我如何让useEffect只在pathname的值没有被定义时才开始呢?

nbnkbykc

nbnkbykc1#

已通过以下ChatGPT修复:

import { useState, useEffect } from "react";
import { db } from "@/lib/firebaseConfig";
import { getDoc, doc } from "firebase/firestore";

function User() {
  const [userId, setUserId] = useState(null);
  const [user, setUser] = useState({});

  useEffect(() => {
    const pathname = window?.location.pathname;
    if (pathname) {
      setUserId(pathname.substring(6));
    }
  }, []);

  useEffect(() => {
    if (userId) {
      const getUser = async () => {
        const docRef = doc(db, "users", userId);
        const docSnap = await getDoc(docRef);
        if (docSnap.exists()) {
          setUser(docSnap.data());
        } else {
          console.log("No such document!");
        }
      };
      getUser();
    }
  }, [userId]);

  return (
    <div>
      {userId && (
        <>
          <h1 className="text-white">{userId}</h1>
          <img src={user.image} />
        </>
      )}
    </div>
  );
}

export default User;

为了修正这个错误,我确保窗口对象只能在浏览器中访问,而不能在服务器端呈现时访问,我把访问窗口对象的代码 Package 在一个typeof window!==“undefined”的检查中。
我将设置用户ID的代码与获取用户数据的代码分开,并使用了两个useEffect钩子来实现这一点。第一个钩子仅在客户端运行,并通过检查窗口对象来设置用户ID。第二个钩子仅在用户ID更改时运行,并从Firestore获取用户数据。
有了这些更改,组件的呈现应该没有任何错误,并且用户ID一可用,就应该获取用户数据。

相关问题