Amplify AppSync 不从客户端上传 S3Object 文件

Amplify AppSync doesn't upload S3Object file from client

首先,https://aws-amplify.github.io/docs/js/api#complex-objects 的文档说:

input CreateTodoInput {
  id: ID
  name: String!
  description: String
  file: S3ObjectInput # This input type will be generated for you
}

我收到错误 Type "S3ObjectInput" not found in document.,我必须手动添加 S3ObjectInput

这是我的架构(文档对此不是很清楚,所以我根据类似的问题将其放在一起)

type Picture @model {
  id: ID!
  file: S3Object!
  url: String!
  rating: Int
  appearedForRanking: Int
}

type S3Object {
  bucket: String!
  key: String!
  region: String!
}

input CreatePictureInput {
  id: ID
  file: S3ObjectInput!
  url: String!
  rating: Int
  appearedForRanking: Int
}

input S3ObjectInput {
  bucket: String!
  region: String!
  localUri: String
  visibility: Visibility
  key: String
  mimeType: String
}

enum Visibility {
  public
  protected
  private
}

这是客户端代码(使用 React)

class PictureUpload extends Component {

  state = { fileUrl: '', file: '', filename: '' }

  handleChange = e => {
    let file = e.target.files[0]
    let filext = file.name.split('.').pop()
    let filename = uuid() + '.' + filext

    this.setState({
      fileUrl: URL.createObjectURL(file),
      filename: filename
    })
  }

  saveFile = async () => {
    let visibility = 'public'

    let fileObj = {
      bucket: awsConfig.aws_user_files_s3_bucket,
      region: awsConfig.aws_user_files_s3_bucket_region,
      key: visibility + '/' + this.state.filename,
      mimeType:'image/jpeg',
      localUri: this.state.fileUrl,
      visibility: visibility
    }

    try {
      const picture = await API.graphql(
        graphqlOperation(mutations.createPicture, {
          input: {
            url: this.state.filename,
            file: fileObj
          }
        })
      )

问题是突变运行没有错误,设置了数据库记录,但文件没有出现在 S3 中。文档说 the SDK uploads the file to Amazon S3 for you. 所以我想我没有忘记添加一些东西。

知道为什么没有上传吗?

仅当使用 aws-appsync 包时才会自动将文件上传到 S3,对于 aws-amplify 您需要使用 Storage.put(...).

自行上传文件

GitHub issue更详细地解释了差异

对于 ReactNative,我发现您不能简单地提供一个 uri,而是一个 blob。试试这个代码:

const response = await fetch(uri);
const blob = await response.blob();

let file = {
  bucket,
  key,
  region,
  localUri: blob,
  mimeType,
};

只要您的身份验证配置正确,这应该会将图像数据发送到 S3。