通过 aws Amplify 使用 Storage 类对本机图像上传进行反应

Posted

技术标签:

【中文标题】通过 aws Amplify 使用 Storage 类对本机图像上传进行反应【英文标题】:React Native Image Upload via aws Amplify using Storage class 【发布时间】:2018-08-26 18:02:33 【问题描述】:

我有一张图片。我想使用 aws-amplify 将它上传到 S3。所有Storage类上传示例均使用文本文档;但是,我想上传一张图片。我正在使用不支持 react-native-fetch-blob 的 expo,并且 react native 还没有 blob 支持。

所以我的选择似乎是:

    通过 lambda 创建节点服务。 仅将 base64 信息上传到 S3,而不是 Blob。

const status = await Permissions.askAsync(Permissions.CAMERA_ROLL); if (status === 'granted') const image = await ImagePicker.launchImageLibraryAsync( quality: 0.5, base64: true ); const base64 = image; Storage.put(`$username-profileImage.jpeg`, base64);

这对吗?

【问题讨论】:

【参考方案1】:

使用 RN BLOB 支持版本编辑更新答案: 现在我已经能够解决这个问题,因为 React Native 已经宣布支持 blob,现在我们只需要 uri。请参阅以下示例:

uploadImage = async uri => 
  const response = await fetch(uri);
  const blob = await response.blob();
  const fileName = 'profileImage.jpeg';
  await Storage.put(fileName, blob, 
    contentType: 'image/jpeg',
    level: 'private'
  ).then(data => console.log(data))
    .catch(err => console.log(err))

旧答案

尽你所能。我最终使用了https://github.com/benjreinhart/react-native-aws3 这非常有效!但不是首选解决方案,因为我想使用 aws-amplify。

【讨论】:

他们的文档对执行如此简单的任务没有多大帮助。在这里也可以找到与此问题相关的有趣讨论:github.com/aws-amplify/amplify-js/issues/576 @Seuential:你能告诉我更多关于代码的细节吗?我遵循 aws-amplify.github.io/docs/js/storage#put 的 React Native 代码,但没有希望 @LuongTruong 您是否收到错误消息?这实际上是与问题相关的所有代码。 @Sequential:感谢您的快速评论。我在 stackoverfow 上创建了一个问题:***.com/questions/53260500/…。使用代码有错误,希望你能看看并帮助我。提前谢谢! @LuongTruong 你有什么版本的 RN?【参考方案2】:

我想为这个问题添加一个更完整的答案。

以下代码允许使用 Expo 中的 ImagePicker 从移动设备库中挑选图像,并使用 AWS 中的 Storage 将图像存储在 S3 中放大

import React from 'react';
import  StyleSheet, ScrollView, Image, Dimensions  from 'react-native'
import  withAuthenticator  from 'aws-amplify-react-native'
import  ImagePicker, Permissions  from 'expo'
import  Icon  from 'native-base'

import Amplify from '@aws-amplify/core'
import Storage from '@aws-amplify/storage'
import config from './aws-exports'

Amplify.configure(config)

class App extends React.Component 
  state = 
    image: null,
  

  // permission to access the user's phone library
  askPermissionsAsync = async () => 
    await Permissions.askAsync(Permissions.CAMERA_ROLL);
  

  useLibraryHandler = async () => 
    await this.askPermissionsAsync()
    let result = await ImagePicker.launchImageLibraryAsync(
      
        allowsEditing: false,
        aspect: [4, 3],
      
    )

    console.log(result);

    if (!result.cancelled) 
      this.setState( image: result.uri )
      this.uploadImage(this.state.image)
    
  

  uploadImage = async uri => 
    const response = await fetch(uri);
    const blob = await response.blob();
    const fileName = 'dog77.jpeg';
    await Storage.put(fileName, blob, 
      contentType: 'image/jpeg',
      level: 'public'
    ).then(data => console.log(data))
      .catch(err => console.log(err))
  

  render() 
    let  image  = this.state
    let height, width = Dimensions.get('window')
    return (
      <ScrollView style=flex: 1 contentContainerStyle=styles.container>
        <Icon 
          name='md-add-circle'
          style=styles.buttonStyle
          onPress=this.useLibraryHandler
        />
        image &&
          <Image source= uri: image  style= width: width, height: height/2  />
        
      </ScrollView>
    );
  


export default withAuthenticator(App,  includeGreetings: true )

const styles = StyleSheet.create(
  container: 
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  ,
  buttonStyle: 
    fontSize: 45, 
    color: '#4286f4'
  
);

【讨论】:

我使用你的代码。该应用程序能够登录,选择图片。但是,收到图片后会出现“网络请求失败”的警告。我认为它来自 const response = await fetch(uri); 我正在使用 Expo 31.0.2。 @Sequential 先生的代码中也发生了同样的事情。 查看这个帖子:***.com/questions/38418998/… 我在 android 上运行您的示例,链接是“static.asiachan.com/Berry.Good.600.42297.jpg”。我认为这不是https 的问题。你有什么建议吗?我愿意听取您的意见 降级到 expo 版本 30.0.1。我的代码在 expo 31 上似乎无法正常运行。还要确保使用 npm 安装 "rn-fetch-blob": "^0.10.13" 和 "buffer": "^5.2.1"。如果您提供另一种通信方式,我很乐意提供我的 package.json。【参考方案3】:

您可以将文件对象传递给 .put 方法

Storage.put('test.png', file,  contentType: 'image/png' )
  .then (result => console.log(result))
  .catch(err => console.log(err));

【讨论】:

这不起作用,因为文件对象依赖于 Blob,但 React Native 尚不支持 Blob,所以除非我弄错了,否则它会出错。

以上是关于通过 aws Amplify 使用 Storage 类对本机图像上传进行反应的主要内容,如果未能解决你的问题,请参考以下文章

aws 中的多个 s3 存储桶放大

通过 GraphQL 键检索 AWS Amplify DataStore 记录

放大未捕获的 AppSync 订阅(承诺中)

通过 AWS amplify 和 ElasticSearch 查找地理和其他字段

AWS Amplify 与 Google 域 DNS

如何禁用 aws amplify vue 身份验证器的注册链接?