Как загрузить простое изображение с мобильного устройства с помощью средства выбора изображений expo в AWS S3?

Я использую Expo с React Native, и я действительно застрял в этом ... expo не поддерживает облачное хранилище Firebase, которое я использовал целую вечность для загрузки своих изображений. Так что у меня остался AWS S3, с которым я никогда не работал. Я уже нашел этот пример на github: https://github.com/expo/image-upload-example/, но я не мог понять, что такое бэкэнд-часть и что такое apiURl, который используется... Прошу прощения, я не предоставил никакой попытки кода, но я полностью потерян, и я могу на самом деле не разбираюсь в огромном количестве бла-бла-бла документации на AWS.

Я сделал это в консоли AWS S3, чтобы доступ к созданному мной сегменту был общедоступным. У меня нет проблем с этим. Мне не нужно, чтобы пользователь был авторизован для загрузки изображений, и любые другие ограничения просто нужны для простой загрузки.

Так что, если кто-нибудь может помочь мне с кодом для этого. Заранее спасибо.


person Ahmed Samy    schedule 01.12.2017    source источник


Ответы (2)


Я специально не использовал Expo, но я настроил свой проект RN, чтобы иметь возможность загружать его на s3. Учитывая приведенный вами пример, он довольно похож на то, что я в итоге сделал.

Поэтому, очевидно, первое, что вам нужно сделать, это настроить корзину на AWS S3. В консоли AWS вы сможете найти свой конкретный ключ доступа и секрет доступа, вам потребуются оба эти параметра вместе с именем вашей корзины.

Идея примера, который вы опубликовали, и то, что я в итоге сделал, заключается в том, чтобы иметь контролируемый сервер, где вы можете безопасно использовать ключ доступа и секрет для создания уникального «подписанного» URL-адреса, который можно использовать для загрузки изображения непосредственно в вашу корзину. . Вы не хотите делать это на своем клиенте, потому что наличие секрета на вашем клиенте просто просит взломать его. Предположим, что ничто на клиенте никогда не является полностью безопасным.

Я уже создавал сервер узлов в качестве серверной части для своего приложения, поэтому эта часть уже была запущена и работала. Если вы новичок в создании внутреннего сервера, я бы посоветовал посмотреть, как настроить сервер Express здесь. Вы можете бесплатно (с ограничениями) разместить приложение на таком сервисе, как heroku. Есть даже отличная статья, описывающая весь этот процесс более подробно здесь . По сути, вы создаете приложение с определенным маршрутом GET, который может быть затронут вашим клиентским приложением. Этот маршрут примет параметр запроса с именем файла, который будет загружен. Вам следует использовать официальный aws sdk, который примет ваш ключ доступа, секретный , имя корзины и имя файла затем сгенерируют уникальный URL-адрес, который будет отправлен обратно в ваше клиентское приложение.

По сути, ваше клиентское приложение подготовит файл для загрузки. У вас должно быть готово имя файла, а затем вы отправляете запрос GET на маршрут URL, который вы только что установили в своем приложении Express. Когда вы получите ответ с вашего сервера, он должен содержать этот уникальный URL-адрес. Затем я использовал библиотеку react native fetch blob, чтобы выполнить PUT запрос к этому уникальному URL, который вы только что получили. Если все пойдет хорошо, он должен безопасно загрузить файл прямо в это ведро. Убедитесь, что вы установили Content-Type в заголовке для типа файла, который вы загружаете.

Я знаю, что это не набор кода, который будет выполнять загрузку, но он должен помочь вам понять, что нужно, и направить вас в правильном направлении.

person Nathan Stowell    schedule 02.12.2017
comment
Я не могу отблагодарить вас достаточно. Вы действительно помогли мне понять механизм всего этого... и я думаю, что теперь я ясно понимаю, что делал тот джентльмен, который привел пример в ссылке, которую я упомянул именно... Большое спасибо и извините, что вам пришлось пройти через все это печатание :) - person Ahmed Samy; 02.12.2017
comment
рад что помогло! - person Nathan Stowell; 03.12.2017
comment
Привет, если вы не возражаете против использования cloudinary, я покажу, как загрузить, а затем получить загруженный URL-адрес для сохранения в firebase medium.com/@ifeoluwaking24/ Также вы можете попробовать перекусить, но не забудьте добавить свой cloud_name и upload_preset snack.expo.io/@ifeking/upload-to-cloudinary - person ifeoluwa king; 06.03.2018

У меня была такая же проблема в течение длительного времени. Это то, что я сделал.

Убедитесь, что вы следуете руководству по усилению для настройки приложения. amplify init, amplify add auth, amplify push, а затем amplify add storage, а затем сделайте это.

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, TextInput } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

function App() {
  const [image, setImage] = useState(null)
  const [name, setName] = useState('Evan Erickson')

  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(`customers/${name}`, 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)```
person Evan Erickson    schedule 12.05.2021