My returns the following.
<View style={{photoBoxStyle}}>
<TouchableOpacity onPress={pickImage} >
{image && <Image source={{ uri: image }} style={{alignSelf: 'center',height:200, width:200, marginTop:10}}/>}
{!image && (
<Button title="Photo +" onPress={pickImage} />
)}
</TouchableOpacity>
</View>
In <WritingPage.js> file, I imported ImagePickerExample, and used it. I really want to get uri of the image that I selected inside ImagePickerExample, but the terminal log keeps telling me
LOG uri does not exist LOG post/49k8N1vrC2YDsHK5Vn2n7EEpkdG3/0.p60n27ciy4 LOG uploadImage tried LOG [TypeError: Network request failed]
What should I do? Please help...
<ImagePickerExample.js>
import React, { useState, useEffect } from 'react';
import { TouchableOpacity, Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
export default function ImagePickerExample(props) {
const [image, setImage] = useState(null);
const [showImagePicker, setShowImagePicker] = useState(false);
const [photoBoxStyle, setPhotoBoxStyle] = useState({
width:'90%',
borderRadius: 10,
borderColor: 'black',
borderWidth: 1,
alignSelf: 'center',
marginTop: 10,
height: 40,
});
useEffect(() => {
if (image) {
setPhotoBoxStyle({
height: 220,
width:'90%',
borderRadius: 10,
alignSelf: 'center',
});
} else {
setPhotoBoxStyle({
width:'90%',
borderRadius: 10,
alignSelf: 'center',
marginTop: 10,
height: 40,
});
}
}, [image]);
const pickImage = async () => {
// No permissions request is necessary for launching the image library
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.canceled) {
setImage(result.assets[0].uri);
setShowImagePicker(true);
}
};
return (
<View style={{photoBoxStyle}}>
<TouchableOpacity onPress={pickImage} >
{image && <Image source={{ uri: image }} style={{alignSelf: 'center',height:200, width:200, marginTop:10}}/>}
{!image && (
<Button title="Photo +" onPress={pickImage} />
)}
</TouchableOpacity>
</View>
);
}
<WritingPage.js>
import {NavigationContainer, useNavigation} from "@react-navigation/native";
import Dell_fill from '../assets/icons/Dell_fill.png'
import Setting_fill from '../assets/icons/Setting_fill.png'
import Lock_fill from '../assets/icons/Lock_fill.png'
import Angry from '../assets/icons/Angry.png'
import Happy from '../assets/icons/Happy.png'
import Sad from '../assets/icons/Sad.png'
import Lol from '../assets/icons/Lol.png'
import Wow from '../assets/icons/Wow.png'
import ImagePickerExample from '../components/ImagePickerExample';
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import 'firebase/compat/storage'
//<Image source={{uri:props.route.params.image}}/> is used when I get the image source from the post screen.
function WritingPage(props){
const navigation = useNavigation();
const [content, setContent]=useState("")
const [feeling, setFeeling]=useState("Happy")
const [readableBy, setReadableBy]=useState("Friends")//should be changed to Myself
const [activeIndex, setActiveIndex] = useState(2);
const [selectedImage, setSelectedImage] = useState(null);
const handleImagePress = (index) => {
setActiveIndex(index);
switch (index) {
case 0:
setFeeling('Sad');
break;
case 1:
setFeeling('Wow');
break;
case 2:
setFeeling('Happy');
break;
case 3:
setFeeling('Lol');
break;
case 4:
setFeeling('Angry');
break;
}
};
const handleImageSelected = (imageUri) => {
console.log('imageUri:'+imageUri)
setSelectedImage(imageUri);
};
const uploadImage =async() => {
try{
const uri = selectedImage;
if(uri===null){
console.log('uri does not exist');
}else{
console.log('uri does exist');
console.log('uri:'+uri);
}
const childPath = `post/${firebase.auth().currentUser.uid}/${Math.random().toString(36)}`;
console.log(childPath);
console.log('uploadImage tried');
const response = await fetch(uri);
const blob = await response.blob();
console.log('response, blob tried');
//firebase storage에 저장하기
const task = firebase.storage().ref().child(childPath).put(blob);
const taskProgress = snapshot =>{
console.log(`transferred: ${snapshot.bytesTransferred}`)
}
const taskCompleted = () =>{
task.snapshot.ref.getDownloadURL().then((snapshot) => {
savePostData(snapshot);
console.log(snapshot);
});
}
const taskError = snapshot =>{
console.log(snapshot)
}
task.on("state_changed", taskProgress, taskError, taskCompleted)
} catch (error) {
console.log(error);
}
}
const savePostData=(downloadURL)=>{
//firestore에 저장하기
firebase.firestore().collection('posts').doc(firebase.auth().currentUser.uid).collection("UserPosts")
.add({
downloadURL,
content,
creation: firebase.firestore.FieldValue.serverTimestamp(),
feeling,
readableBy
}). then((function () {
props.navigation.navigate('HomeScreen');
}))
}
return(
<View style={styles.container}>
<ImageBackground source={m1}
resizeMode="cover" style={styles.image}
>
<View style={styles.frame}>
<Text style={styles.title}>오늘의 기억</Text>
<TouchableOpacity onPress= {()=> navigation.navigate('HomeScreen')} style={styles.exitButton}>
<Image source={Dell_fill} />
</TouchableOpacity>
<TouchableOpacity onPress= {()=> navigation.navigate('')} style={styles.button1}>
<Image source={Setting_fill} />
</TouchableOpacity>
<TouchableOpacity onPress= {()=> navigation.navigate('')} style={styles.button2}>
<Image source={Lock_fill} />
</TouchableOpacity>
</View>
<View style={styles.frame2}>
<Text style={styles.chooseText}>오늘의 표정을 선택해주세요</Text>
<View style={styles.emoticonBox}>
<TouchableOpacity style={styles.imageButton} onPress={()=>handleImagePress(0)}>
<Image source={Sad} style={[styles.margin,{tintColor: activeIndex === 0 ? 'red' : 'black'}]} />
</TouchableOpacity>
<TouchableOpacity style={styles.imageButton} onPress={()=>handleImagePress(1)}>
<Image source={Wow} style={[styles.margin,{tintColor: activeIndex === 1 ? 'red' : 'black'}]}/>
</TouchableOpacity>
<TouchableOpacity style={styles.imageButton} onPress={()=>handleImagePress(2)}>
<Image source={Happy} style={[styles.margin,{tintColor: activeIndex === 2 ? 'red' : 'black'}]}/>
</TouchableOpacity>
<TouchableOpacity style={styles.imageButton} onPress={()=>handleImagePress(3)}>
<Image source={Lol} style={[styles.margin,{tintColor: activeIndex === 3 ? 'red' : 'black'}]}/>
</TouchableOpacity>
<TouchableOpacity style={styles.imageButton} onPress={()=>handleImagePress(4)}>
<Image source={Angry} style={[styles.margin,{tintColor: activeIndex === 4 ? 'red' : 'black'}]}/>
</TouchableOpacity>
</View>
</View>
<View style={styles.frame3}>
<View>
<ImagePickerExample onImageSelected={handleImageSelected}/>
</View>
<View style={styles.dateBox}>
<Text style={styles.date}>Date: ...</Text>
</View>
<TextInput
placeholder="Write a Caption . . ."
onChangeText={(content)=> setContent(content)}
multiline={true}
/>
<TouchableOpacity style={styles.buttonContainer} onPress={()=>uploadImage()}>
<Text>Save</Text>
</TouchableOpacity>
</View>
</ImageBackground>
</View>
// 로그인 페이지로 이동하는 버튼
//<Button title="go to main" onPress={()=>navigation.navigate('LogIn')}/>
);
};
const styles = StyleSheet.create({
buttonContainer:{
backgroundColor:'white',
alignItems: 'center',
},
container:{
flex:1,
},
frame:{
height: '100%',
width: '100%',
borderRadius: 40,
backgroundColor: 'rgba(177,137,176,0.8)',
justifyContent: 'center',
alignItems: 'center',
alignSelf: "center",
position: 'absolute',
textAlign: 'center',
flexDirection: 'column',
flexWrap: 'wrap',
},
frame2:{
height: '12%',
width: '90%',
borderRadius: 30,
backgroundColor: '#E1BFDF',
justifyContent: 'center',
alignItems: 'center',
alignSelf: "center",
position: 'absolute',
textAlign: 'center',
top: 70,
marginBottom: 10,
},
emoticonBox:{
flexDirection: 'row',
justifyContent: 'space-between',
},
frame3:{
height: '75%',
width: '90%',
borderRadius: 30,
backgroundColor: '#E1BFDF',
alignSelf: "center",
top: '9.4%',
flexDirection: 'column',
},
photoBox:{
height: 'auto',
width:'90%',
borderRadius: 10,
borderColor: 'black',
borderWidth: 1,
alignSelf: 'center',
marginTop: 10,
minHeight: 40,
},
dateBox:{
height: 25,
width:'90%',
borderRadius: 10,
borderColor: 'red',
borderWidth: 1,
marginTop: 10,
alignSelf: 'center',
},
image:{
flex: 1,
justifyContent: 'center',
},
title:{
top:24,
fontSize: 24,
fontWeight: '400',
position: "absolute",
left: 30,
},
exitButton:{
width: 50,
height: 50,
backgroundColor: '#A381A1',
borderColor: '#6E8D9D',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
top: 10,
right: 10,
position: 'absolute',
},
button1:{
width: 50,
height: 50,
backgroundColor: '#A381A1',
borderColor: '#6E8D9D',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
top: 10,
right: 70,
position: 'absolute',
},
button2:{
width: 50,
height: 50,
backgroundColor: '#A381A1',
borderColor: '#6E8D9D',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
top: 10,
right: 130,
position: 'absolute',
},
describingText:{
top: '9%',
fontSize: 24,
fontWeight: '400',
textAlign: 'center',
position: "absolute",
},
inText: {
fontSize: 24,
fontWeight: '400',
},
margin: {
margin: '2%',
},
imageButton:{
backgroundColor:'',
padding:10,
alignItems: "center",
},
chooseText:{
textAlign: 'center',
top: '5%',
fontSize: 24,
fontWeight: '400',
},
date:{
textAlign: 'left',
left: '5%',
top: '3%',
fontSize: 14,
fontWeight: '400'
}
});
export default WritingPage;
<ImagePickerExample.js>
if (!result.canceled) {
props.onImageSelected(result.assets[0].uri);
setImage(result.assets[0].uri);
setShowImagePicker(true);
}
Your two components WritingPage
and ImagePickerExample
need to be able to communicate with each other via props. Here's what you have already which helps you get achieve this (1 & 2), and the one final step that you are missing (3):
ImagePickerExample
is a child of WritingPage
WritingPage
tells the ImagePickerExample
what to do when in gets an image. You defined a defining a handler function handleImageSelected
and passed it down using a prop onImageSelected
: <ImagePickerExample onImageSelected={handleImageSelected}/>
. (parent => child)ImagePickerExample
tells the WritingPage
when it gets an image by calling the onImageSelected
prop which was set by the parent. (child => parent)All that is left to do is to call props.onImageSelected
with the uri (step 3). You'll do this in the ImagePickerExample
component, inside the pickImage
handler, once you've checked that you have a valid result.