How to upload multiple images to AWS S3 in react-native App - Part 1
Tags: reactnative, javascript, aws, mobile
Published: 2021-11-26 07:55:51

Most mobile app has user taken images functionality and store those images in cloud storage. So in this article, I will cover how to get multiple images from the gallery and I'll make part 2 for uploading those to AWS S3.

# Get multi select images from the gallery
I used `react-native-image-crop-picker` for multiple selections of images from the gallery of both iOS and Android devices.

###Install react-native-image-crop-picker
Please go through their library to install and configure this package [here](https://github.com/ivpusic/react-native-image-crop-picker#install).

###Define state and basic UI
I created a button and on its press, I am opening the phone's gallery to select images.
```javascript
  <TouchableOpacity onPress={() => openImageLibrary()}>
     <Text>Select Photos</Text>
  </TouchableOpacity>
```
now to store these images I created a state using React hooks
```javascript
  const [images, setImages] = useState([]);
```

###Request camera permissions
Before opening the gallery of the phone, we have to take user permission to access the gallery and photos. So for that, I used `PermissionsAndroid` method.
```javascript
 const requestExternalWritePermission = async () => {
    if (Platform.OS === 'android') {
      try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.CAMERA,
          {
            title: 'Access to photos',
            message: 'Our App would like to access your photos on your device',
            buttonNegative: 'Deny',
            buttonPositive: 'Allow',
          },
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
          return granted;
        } else {
          console.log('Camera permission denied');
        }
      } catch (err) {
        console.warn(err);
      }
    } else {
      return true;
    }
  };
```
This function is checking if the platform or device is `android` then it would show the dialog box with a message and buttons below to accept or reject the permissions.  
Before that, I also defined user permission in `AndroidManifest.xml` file like this
```javascript
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
```
*Note: I didn't need to add permissions for the iOS side at this point because during the installation process of `react-native-image-crop-picker` it will ask you to add camera and gallery permissions in `info.plist` file.*

###Open image library
Now I defined my method to select photos from the gallery and storing in my `images` state.
```javascript
const openImageLibrary = async () => {
    let isStoragePermitted = await requestExternalWritePermission();
    if (isStoragePermitted) {
      openPicker({
        multiple: true,
        mediaType: 'photo',
        maxFiles: `4`,
        showsSelectedCount: true,
      }).then(imgs => {
        if (imgs.length <= 4) {
          setImages([...images, ...imgs]);
        } else {
          setImages([...images]);
          ToastAndroid.show("Maximum of 4 images allowed", ToastAndroid.SHORT);
        }
      });
    }
  };
```
In this function, I am calling `requestExternalWritePermission` method which I described above, if the user clicks granted then it will open the default gallery view of the user device and will allow the user to select multiple photos. I defined `maxFiles` as 4, you can define your limit as you want.

*Note: `maxFiles` and `showsSelectedCount` prop only works for iOS devices so you would have to define custom logic for android devices.*

So I am showing `ToastAndroid` saying **Maximum of 4 images allowed** if the user selects more than 4 images from the android device.

###Display images in your App
Now I display the images on screen like this
```javascript
  {images.length > 0 &&
    images.map(image => (
    <View key={image.path}>
      <Image 
       style={{
         width: 80,
         height: 80,
        }}
       source={{uri: image.path}}
      />
    </View>
  ))}
```

Please go to part 2 to upload these images to AWS