Reputation: 825
I have a simple React Native application that utilizes an AWS bucket for photo storage. I currently have the AWS config coded in a file in which it is being used but I would like to move it to it's own file and then import it when needed.
This is what the config.js file looks like when abstracted from the other files:
const config = {
keyPrefix: 'Uploaded Photos/',
bucket: 'rn-mobile-app-bucket',
region: 'us-east-2',
accessKey: 'MYACCESSKEY',
secretKey: 'MYSECRETKEY',
successActionStatus: 201
}
This is the file that it is currently being used in:
import React, { useEffect, useState } from 'react';
import { Button, View, Text, TextInput, Picker } from 'react-native';
import { Header } from 'react-native-elements';
import { styles } from './styles.js';
import * as ImagePicker from 'expo-image-picker';
import { RNS3 } from 'react-native-aws3';
import Modal from 'react-native-modal';
const FormSubmit = ({navigation, route}) => {
const [Name, onChangeName] = useState(null);
const [Phone, onChangePhone] = useState(null);
const [Email, onChangeEmail] = useState(null);
const [selectedValue, setSelectedValue] = useState(null);
const [MileMarker, onChangeMileMarker] = useState(null);
const [Comments, onChangeComments] = useState(null);
const [RoadName, onChangeRoadName] = useState(null);
const [image, setImage] = useState(null);
const [hasPermission, setHasPermission] = useState(null);
const [isModalVisible, setModalVisible] = useState(false);
const counties = ["Barbour", "Berkeley", "Boone", "Braxton", "Brooke", "Cabell", "Calhoun", "Clay", "Doddridge", "Fayette", "Gilmer", "Grant", "Greenbrier", "Hampshire", "Hancock", "Hardy",
"Harrison", "Jackson", "Jefferson", "Kanawha", "Lewis", "Lincoln", "Logan", "Marion", "Marshall", "Mason", "Mercer", "Mineral", "Mingo", "Monongalia", "Monroe", "Morgan", "McDowell",
"Nicholas", "Ohio", "Pendleton", "Pleasants", "Pocahontas", "Preston", "Putnam", "Raleigh", "Randolph", "Ritchie", "Roane", "Summers", "Taylor", "Tucker", "Tyler", "Upshur", "Wayne",
"Webster", "Wetzel", "Wirt", "Wood", "Wyoming"]
//This needs to happen when I press the button I think but it doesnt really seem to work if I do.
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 {status} = await ImagePicker.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
setImage(result.uri);
toggleModal();
}
};
const takeImage = async () => {
let result = await ImagePicker.launchCameraAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
setImage(result.uri);
toggleModal();
}
};
//POST a new form to the database
const postForm = async () =>{
fetch('http://10.0.2.2:5000/forms', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
Name: Name,
Phone: Phone,
Email: Email,
County: selectedValue,
RoadName: RoadName,
MileMarker: MileMarker,
Comments: Comments,
Path: "https://rn-mobile-app-bucket.s3.us-east-2.amazonaws.com/Uploaded+Photos/" + Name + Date.now()
})
}).then(response =>{
if(response.ok){
return response.json();
}
}).then(data => console.log(data));
}
//Save image to AWS S3 bucket
const saveImage = async () => {
const file = {
uri: image,
name: Name + Phone, //This needs to be a better naming convention
type: 'image/png'
}
const config = {
keyPrefix: 'Uploaded Photos/',
bucket: 'rn-mobile-app-bucket',
region: 'us-east-2',
accessKey: 'MYACCESS',
secretKey: 'SECRETKEY',
successActionStatus: 201
}
RNS3.put(file, config).then((response) => {
console.log(response);
});
}
const toggleModal = () => {
setModalVisible(!isModalVisible);
};
return (
<View style={styles.container}>
<Header
//leftComponent={{ icon: 'menu', color: '#fff' }}
centerComponent={{ text: 'Create request', style: { color: '#fff', fontSize: 25} }}
//rightComponent={{ icon: 'home', color: '#fff' }}
/>
<View style={styles.rowContainer}>
<TextInput
style={styles.input}
placeholder = "Name"
onChangeText={onChangeName}
value={Name}
/>
</View>
<View style={styles.rowContainer}>
<TextInput
style={styles.input}
placeholder = "Phone"
onChangeText={onChangePhone}
value={Phone}
/>
</View>
<View style={styles.rowContainer}>
<TextInput
style={styles.input}
placeholder = "Email"
onChangeText={onChangeEmail}
value={Email}
/>
</View>
<View style={styles.rowContainer}>
<Picker
style={styles.charPicker}
mode="dropdown"
selectedValue={selectedValue}
onValueChange={(itemValue, itemIndex) => setSelectedValue(itemValue)}
>
{counties.map((item, index) => {
return (<Picker.Item label={item} value={item} key={index}/>)
})}
</Picker>
</View>
<View style={styles.rowContainer}>
<TextInput
style={styles.input}
placeholder = "Mile Marker"
onChangeText={onChangeMileMarker}
value={MileMarker}
/>
</View>
<View style={styles.rowContainer}>
<TextInput
style={styles.input}
placeholder = "Road Name"
onChangeText={onChangeRoadName}
value={RoadName}
/>
</View>
<View style={styles.rowContainer}>
<TextInput
style={styles.textArea}
placeholder = "Describe the problem..."
numberOfLines={10}
multiline={true}
onChangeText={onChangeComments}
value={Comments}
/>
</View>
<Button title="Upload Photo" onPress={toggleModal} />
<Button
style = {styles.button}
title="Submit"
onPress={() => {
saveImage();
postForm();
navigation.navigate('ThankYou');
}}
color="#19AC52"
/>
<Modal isVisible={isModalVisible}>
<View style={{flex: 1}}>
<Text>Hello!</Text>
<Button title="Camera Roll" onPress={pickImage} />
<Button title="Camera" onPress={takeImage} />
<Button title="Cancel" onPress={toggleModal} />
</View>
</Modal>
</View>
);
}
export default FormSubmit;
In which the section in question is this part:
//Save image to AWS S3 bucket
const saveImage = async () => {
const file = {
uri: image,
name: Name + Phone, //This needs to be a better naming convention
type: 'image/png'
}
const config = {
keyPrefix: 'Uploaded Photos/',
bucket: 'rn-mobile-app-bucket',
region: 'us-east-2',
accessKey: 'ACCESSKEY',
secretKey: 'SECRETKEY',
successActionStatus: 201
}
RNS3.put(file, config).then((response) => {
console.log(response);
});
}
If I comment out the config struct and try to import it like this:
import * as config from '../../config';
or this
import config from '../../config';
I get the error
[Unhandled promise rejection: Error: Must provide `bucket` option with your AWS bucket name]
What am I doing wrong and how can I properly import the config struct?
Upvotes: 0
Views: 316
Reputation: 948
In your config.js try changing it to export const config =
And then when importing it change it to import {config} from ../../config
and pass that config object straight into the s3.put call
A handy cheatsheet to use for imports/exports is : https://medium.com/dailyjs/javascript-module-cheatsheet-7bd474f1d829
Upvotes: 1