AWS graphQL错误:“变量“输入”已将非空类型“ ID!”的空值强制为空!”

时间:2019-06-09 21:41:08

标签: javascript amazon-web-services react-native graphql aws-sdk

我正在使用本机反应和aws扩增与graphQL接口。但是,在进行此突变时,我收到错误消息“变量'input'已将NonNull类型'ID!'强制转换为Null值。”

addStudent = async (classData) => {
    try {
    let user = await Auth.currentAuthenticatedUser();
    const emailAttribute = user.attributes.email;
    const studentObj = {
      name: this.state.studentName,
      email: emailAttribute,
      class: classData.id,
    }
    await API.graphql(graphqlOperation(mutations.createStudent, { input: studentObj }));
} catch (err) {
    console.error(err);
}
}

这是我的模式:

type Class @model @auth(rules: [{ allow: owner, queries: null}]) {
id: ID!
name: String!
password: String!
email: String!
students: [Student] @connection(name: "ClassStudents")
}

type Student @model @auth(rules: [{ allow: owner, queries: null}]) {
id: ID!
name: String!
email: String!
class: Class! @connection(name: "ClassStudents")
attendance: [Attendance] @connection(name: "StudentAttendance")
}

这是我要称呼为AWS生成的突变:

export const createStudent = `mutation CreateStudent($input: CreateStudentInput!) {
  createStudent(input: $input) {
id
name
email
class {
  id
  name
  password
  email
  students {
    nextToken
  }
}
attendance {
  items {
    id
    date
  }
  nextToken
}
}
}
`;

我尝试了类似问题的解决方案,例如更改mutator参数的语法,但错误仍然存​​在。知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

是的,我认为突变的第一行应该是这样;

export const createStudent = `mutation CreateStudent($input: ID!)

答案 1 :(得分:0)

问题不是学生证。与此连接有关:

class: Class! @connection(name: "ClassStudents")

Class项目是GraphQL连接类型。这不是身份证。您可能有一个类似classStudentIdstudentClassId的列。我仍在确切地了解如何在AppSync中自动创建此列,但这是AppSync在DynamoDB中管理连接的方式。您必须指定该id列,而不是class:

例如:

addStudent = async (classData) => {
  try {
    let user = await Auth.currentAuthenticatedUser();
    const emailAttribute = user.attributes.email;
    const studentObj = {
      name: this.state.studentName,
      email: emailAttribute,
      studentClassId: classData.id,
    }
    await API.graphql(graphqlOperation(mutations.createStudent, { input: studentObj }));
  } catch (err) {
    console.error(err);
  }
}

我的例子

作为一个例子,我可以分享我刚刚尝试解决的问题,导致我在尝试修复该问题时出现在这里:

架构

type Message @model
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      { allow: groups, groups: ["everyone"], operations: [read] }
    ]
  )
  @key(fields: ["associationId", "createdAt"]) {
  id: ID!
  associationId: String!
  content: String!
  createdAt: AWSDateTime!
  author: User! @connection(name: "UserMessages", keyField: "owner")
}

突变

export const createMessage = /* GraphQL */ `
  mutation CreateMessage(
    $input: CreateMessageInput!
    $condition: ModelMessageConditionInput
  ) {
    createMessage(input: $input, condition: $condition) {
      id
      associationId
      content
      createdAt
      owner
      author {
        id
        firstName
        lastName
        email
        phone
        avatar {
          bucket
          region
          key
        }
      }
    }
  }
`;

通常,我可以这样创建一条消息:

const submitData = {
  associationId: association.id,
  content: fields.message,
}
await API.graphql(graphqlOperation(CreateMessage, { input: submitData }))

Amplify将从Cognito(使用auth)获取当前用户ID,并为我创建一个唯一ID。

但是,由于我指定了owner为连接键字段,所以现在我不得不手动将用户ID添加到所有者列,所以我不能将其留空并依靠Amplify了。

我已经使所有者成为连接到用户表的 DynamoDB要求,而不仅仅是Amplify可以使用的认知连接字段。我可以在authorId之类的单独列中指定用户ID,但是由于User表仍然使用Cognito ID,因此我试图将它们压缩为一列...所以现在我必须这样做遇到与您相同的错误:

const submitData = {
  associationId: association.id,
  content: fields.message,
  owner: user.id,
}
await API.graphql(graphqlOperation(CreateMessage, { input: submitData }))

您的情况显然有所不同,但是您需要找出它实际上如何存储Class id并手动指定它。或者,您可以强制它使用您想要的键字段,例如classId,但不能使用连接项本身。那不是它的存储方式。