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

时间:2019-08-01 23:23:23

标签: reactjs amazon-web-services graphql aws-amplify aws-appsync

首先,当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
          }
        })
      )

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

知道为什么不上传吗?

2 个答案:

答案 0 :(得分:0)

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

GitHub issue详细解释了差异

答案 1 :(得分:0)

对于ReactNative,我发现您不能简单地提供一个uri,而是一个Blob。请尝试以下代码:

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

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

只要正确配置了身份验证,这便会将图像数据保存到S3。