AWS Amplify 和 Next.JS with GraphQL Server Error No current user from getStaticPaths

AWS Amplify and Next.JS with GraphQL Server Error No current user from getStaticPaths

我在从 Amplify 的 API Graphql 访问数据时遇到问题,它一直在返回

Server Error
Error: No current user

我一直在学习这个教程:https://youtu.be/13nYLmjZ0Ys?t=2292

我知道我已登录 Amplify,因为如果我进入不同的页面,我可以获取用户 Auth,甚至可以显示 SignOut 按钮。但无论出于何种原因,我不确定为什么会收到此错误

import { API } from "aws-amplify";
import { useRouter } from "next/router";
import { listActivations, getActivation } from "../../graphql/queries";

const Activation = ({ activation }) => {
  const router = useRouter();
  if (router.isFallback) {
    return <div>Loading</div>;
  }
  return <div>{activation.title}</div>;
};
export default Activation;

export async function getStaticPaths() {
  const SSR = withSSRContext();
  console.log("static paths");
  const activationData = await SSR.API.graphql({
    query: listActivations,
  });
  console.log("activationData", activationData);
  const paths = activationData.data.listActivations.items.map((activation) => ({
    params: { id: activation.id },
  }));
  return {
    paths,
    fallback: true,
  };
}

export async function getStaticProps({ params }) {
  const SSR = withSSRContext(); // added SSR, but still getting error
  console.log("static props");
  const { id } = params;
  const activationData = await SSR.API.graphql({
    query: getActivation,
    variables: { id },
  });
  return {
    props: {
      activation: activationData.data.getActivation,
    },
  };
}

出现控制台日志static paths,然后出现错误。

您认为它与我的 GraphQL 架构有什么关系吗?

type User @model @auth(rules: [{ allow: owner, ownerField: "username" }]) {
  id: ID!
  username: String!
  email: String!
  userType: UserType
}

type Activation
  @model
  @key(
    name: "activationsByStudentId"
    fields: ["student"]
    queryField: "activationsByStudentId"
  )
  @auth(
    rules: [
      { allow: groups, groups: ["Admin"] }
      { allow: owner }
      {
        allow: owner
        ownerField: "studentId"
        operations: [create, update, delete]
      }
      { allow: private, operations: [read] }
      { allow: public, operations: [read] }
    ]
  ) {
  id: ID!
  studentId: ID!
  title: String!
  student: Student @connection(fields: ["studentId"])
  teachers: [TeachersActivations] @connection(name: "ActivationTeachers")
}

编辑:我还添加了用户模型,看看这是否也是一个原因。

由于 getStaticPropsgetStaticPaths 都是在构建时调用的,并且在服务器上 fallback 等于 true 时,您需要为 SSR 配置 Amplify (服务器端渲染)。请务必查看 SSR Support for AWS Amplify JavaScript Libraries.

解决方法:首先为SSR配置Amplify:

Amplify.configure({ ...awsExports, ssr: true });

则需要使用withSSRContext,并添加authMode参数。引用上面的 link:

For example, take an AppSync GraphQL API that is backed by an identity provider such as Amazon Cognito User pools, Okto, or Auth0. Some GraphQL types may require a user to be authenticated to perform certain requests. Using the API class, the user identity will now automatically be configured and passed into the API request headers:

const SSR = withSSRContext();
const activationData = await SSR.API.graphql({
  query: listActivations,
  authMode: "AMAZON_COGNITO_USER_POOLS"
});

仍然,我无法弄清楚为什么这不起作用,所以我决定将查询移至客户端

const [activation, setActivation] = useState(null);

const router = useRouter();
const { aid } = router.query;

useEffect(() => {
  if (!aid) return;

  async function activationDataFromClient() {
    try {
      const getActivationData = await API.graphql({
        query: getActivation,
        variables: {
          id: aid,
        },
      });

      setActivation(getActivationData.data.getActivation);
    } catch (err) {
      console.log("error fetching activation data: ", err);
    }
  }
  activationDataFromClient();
}, [aid]);