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

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

所以我的选择似乎是:

  1. 通过 lambda 创建节点服务。
  2. 仅将 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); }

这对吗?

【问题讨论】:

    标签: javascript amazon-web-services react-native blob aws-amplify


    【解决方案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 上创建了一个问题:stackoverflow.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 先生的代码中也发生了同样的事情。
    • 我在 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,所以除非我弄错了,否则它会出错。
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2018-07-09
    • 1970-01-01
    • 2019-01-15
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    相关资源
    最近更新 更多