反应本机AWS S3上传

时间:2020-04-23 12:31:36

标签: amazon-web-services react-native amazon-s3 file-upload

我正在使用react-native-image-pickerreact-native-s3-upload将图像上传到s3存储桶。

var newUser = _mapper.Map<User>(dto);

,我得到了这样的回复,但没有上传图片。

 RNS3.put(file, AWSOptions)
    .then((response) => {
        if (response.status !== 201) {
           throw new Error('Failed to upload image to S3');
         }
    })
    .catch(function (error) {
         console.log('Error', JSON.stringify(error));
         throw error;
    });

5 个答案:

答案 0 :(得分:2)

对于名为react-native-aws3的类似库,我有完全相同的问题。 似乎与新的React Native版本0.62.2有关,因为我今天尝试升级(我的先前版本是0.61.5),并且该库以前可以工作。

我不知道两个库是否都使用一个公共API,现在新RN中已损坏了该API,但我建议您同时降级。

答案 1 :(得分:1)

我遇到了同样的问题,并尝试了几天来解决它。这是我想出来的。

确保您遵循放大指南并设置amplify initamplify add auth,然后执行amplify push

然后执行 amplify add storage 并遵循此处的指南 (https://docs.amplify.aws/lib/storage/upload/q/platform/js)。然后复制此代码。

import Amplify, { Storage } from 'aws-amplify'
import config from './src/aws-exports'
// import awsconfig from './aws-exports';
// Might need to switch line 7 to awsconfig 
Amplify.configure(config)

import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform, StyleSheet, Text } from 'react-native';
import * as ImagePicker from 'expo-image-picker';


function App() {
  const [image, setImage] = useState(null)

  useEffect(() => {
    (async () => {
      if (Platform.OS !== 'web') {
        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
        if (status !== 'granted') {
          alert('Sorry, we need camera roll permissions to make this work!');
        }
      }
    })();
  }, []);

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });
    
    console.log(result) 

    async function pathToImageFile(data) {
      try {
        const response = await fetch(data);
        const blob = await response.blob();
        await Storage.put(`customer/images`, blob, {
          contentType: 'image/jpeg', // contentType is optional
        });
      } catch (err) {
        console.log('Error uploading file:', err);
      }
    }
    
    // later
    
    pathToImageFile(result.uri);
  }


  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Pick an image from camera roll" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      <Button title="Upload image" onPress={() => {alert(image)}} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default withAuthenticator(App)```

答案 2 :(得分:0)

我找到了另一个模块(aws-sdk),用于将文件上传到RN 62版本的S3存储桶。

我还很好地使用了base64-arraybufferreact-native-fs模块。

const s3bucket = new S3({
      accessKeyId: XXXXXXXXXX,
      secretAccessKey: XXXXXXXXXXXX,
      Bucket: XXXXXXXXX,
      signatureVersion: 'v4',
    });
    let contentType = 'image/jpeg';
    let contentDeposition = 'inline;filename="' + file.name + '"';

    const base64 = await fs.readFile(file.uri, 'base64');

    const arrayBuffer = decode(base64);

    s3bucket.createBucket(() => {
      const params = {
        Bucket: XXXXXXXXXXX,
        Key: file.name,
        Body: arrayBuffer,
        ContentDisposition: contentDeposition,
        ContentType: contentType,
      };
      s3bucket.upload(params, (err, data) => {
        if (err) {
          console.log('error in callback');
          console.log(err);
          setSpinner(false);
        }
        console.log('success');
        console.log(data.Location);
        setImageUrl(data.Location);
        setSpinner(false);
      });
    });

答案 3 :(得分:0)

问题出在RN >= 0.62

您可以回滚到版本< 0.62,也可以遵循我的操作。

我通过注释android/app/src/debug/java/**/ReactNativeFlipper.java中的第43行来解决了该问题

NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
  new NetworkingModule.CustomClientBuilder() {
    @Override
    public void apply(OkHttpClient.Builder builder) {
      // builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); <---- This line
    }
  });
client.addPlugin(networkFlipperPlugin);
client.start();

执行此操作后,您将需要重建应用程序。

希望这会有所帮助。

答案 4 :(得分:0)

AWS S3上传是React Native AWS amplify提供的强大服务。这里的问题可能是由R​​eact Native版本或软件包的不正确配置引起的。您可以在此处查看一些精彩的文章,这些文章绝对可以帮助您根据项目配置正确集成React Native AWS Amplify,并使AWS S3上传也正常工作。