我想在Expo的我的React Native应用程序中上传图像。 ImagePicker有效,直到我要获取uri。当打印出图像结果时,ImagePickers发现,结果看起来很不错
Object {
"cancelled": false,
"height": 1280,
"type": "image",
"uri":"file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540lifdaai%252FTurfMeisterApp/ImagePicker/d1b246ff-a5d0-4e38-a23e-7cc726c5290f.jpg",
"width": 722,
}
我想这与本地主机有关,但我不确定。我认为它查看的是笔记本电脑而非手机上的文件?
import React, {Component} from "react";
import {
View, Text, StyleSheet, Button, Image, TouchableOpacity,
Alert, TextInput, KeyboardAvoidingView,
} from "react-native";
import {Avatar, Divider, Header} from "react-native-elements";
import {f, auth, database} from "../config/config";
import {Permissions, ImagePicker} from 'expo';
class GlobalAccount extends Component {
constructor(props) {
super(props);
this.state = {
user_code: "Chen",
user_object: "Unknown",
user_avatar: "Unknown",
user_first_name: "Unknown",
user_last_name: "Unknown",
user_email: "Unknown",
user_city: "Unknown",
user_change_password: "",
imageID: this.uniqueId(),
imageUploading: false,
imageSelected: false,
imageCaptation: '',
editProfile: true,
};
}
s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
uniqueId = () => {
return this.s4() + "-" + this.s4() + "-" + this.s4() + "-" + this.s4() + "-"
+ this.s4() + "-" + this.s4() + "-" + this.s4() + "-" + this.s4();
};
_checkPermissiosn = async () => {
const {statusCamera} = await Permissions.askAsync(Permissions.CAMERA);
this.setState({cameraPermission: statusCamera});
const {statusCameraRoll} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState({cameraRollPermission: statusCameraRoll});
};
findNewImage = async () => {
this._checkPermissiosn();
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'Images',
allowsEditing: true,
quality: 1,
});
console.log(result);
if (!result.cancelled) {
console.log("upload image");
this.uploadImage(result.uri);
} else {
console.log("cancceld")
}
};
uploadImage = async (uri) => {
var that = this;
var userId = f.auth().currentUser.uid;
var imageId = this.state.imageID;
var re = /(?:\.([^.]+))?$/;
var ext = re.exec(uri)[1];
this.setState({
currentFileType: ext,
// uploading: true,
});
console.log(uri);
const response = await fetch(uri) // Here it goes wrong
.catch((error) => console.log("error occured: " + error));
const blob = await response.blob();
var FilePath = imageID + '.' + that.state.currentFileType;
const ref = storage.ref('User/' + userId + "/img").child(FilePath);
var snapshot = ref.put(blob).on("state_changed", snapshot => {
console.log("progress", snapshot.bytesTransferred, snapshot.totalBytes);
});
/*
uploadTask.on('state_changed', function (snapshot) {
var progress = ((snapshot.bytesTransferred / snapshot.totalBytes) * 100).toFixed(0);
console.log("Upload is " + progress + "% complete");
that.setState({
progress: progress,
});
},
function (error) {
console.log("error with upload " + error);
}, function () {
that.setState({progress: 100});
uploadTask.snapshot.ref.getDownloadURL().then(function (downloadURL) {
console.log(downloadURL);
that.processUpload(downloadURL);
});
});
*/
};
/*
processUpload = (imageUrl) => {
// set needed info
var userId = f.auth().currentUser.uid;
var dateTime = Date.now();
var timestap = Math.floor(dateTime / 1000);
// Build photo object
var photoObj = {
author: userId,
timestamp: timestap,
url: imageUrl,
imageId: this.state.imageID,
};
console.log('before uplaoding');
// upload to the database
database.ref('photos/' + imageId).set(photoObj);
console.log("after uploading");
// atabase.ref('photos/' + imageId).set(photoObj);
};
*/
/**
* Testing purpose only.
*/
alertElement() {
Alert.alert(
"Change your profile photo?",
"",
[
{text: "Nee"},
{text: "Yes", onPress: () => this.findNewImage()},
]
)
}
/**
* Before mounting the scene, load the data
*/
componentWillMount() {
this.loadDataFromDatabase();
}
/**
* When pressed, logout the user.
*/
signUserOut = () => {
var that = this;
auth.signOut()
.then(console.log("user is signed out"))
.catch((error) => console.log("error occured while signing user out: ", error));
that.setState({
loggedin: false
})
};
/**
* Download the data from the server.
* Only data corresponding to the user.
*/
loadDataFromDatabase = () => {
this.setState({
refresh: true,
groups: [],
});
var that = this;
// exampleUser must be the user who is logged in.
database.ref('Users').child(this.state.user_code).once("value")
.then(function (snapshot) {
const exists = (snapshot.val() !== null);
if (exists) {
var user_object = snapshot.val();
console.log("user_object is : ", user_object.avatar);
console.log("user name is " + user_object.firstName);
that.setState({
user_object: user_object,
user_avatar: user_object.avatar,
user_first_name: user_object.firstName,
user_last_name: user_object.lastName,
user_email: user_object.email,
});
}
}).catch(error => console.log(error));
};
uploadDataToFirebase = () => {
var updateArray = {};
updateArray['/Users/Chen/firstName'] = this.state.user_first_name;
updateArray['Users/Chen/lastName'] = this.state.user_last_name;
updateArray['Users/Chen/email'] = this.state.user_email;
updateArray['Users/Chen/City'] = this.state.user_city;
database.ref().update(updateArray);
};
/**
* Render the 'my account' page.
* @returns {*the account page.*}
*/
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.imageView}
onLongPress={() => {
this.alertElement()
}}
>
<Image style={styles.image}
source={({uri: this.state.user_avatar})}
/>
</TouchableOpacity>
<KeyboardAvoidingView
style={{backgroundColor: "purple"}}
behavior="position" //padding, height
>
<View style={{flexDirection: 'column', alignItems: 'center'}}>
<View>
<Text>Profile</Text>
</View>
<View style={styles.InformationBox}>
<Text style={styles.itemName}>First name</Text>
<TextInput
style={styles.textInput}
onChangeText={(first_name) => this.setState({user_first_name: first_name})}
value={this.state.user_first_name}
/>
</View>
<View style={styles.InformationBox}>
<Text style={styles.itemName}>Last name</Text>
<TextInput
style={styles.textInput}
onChangeText={(last_name) => this.setState({user_last_name: last_name})}
value={this.state.user_last_name}
/>
</View>
<View style={styles.InformationBox}>
<Text style={styles.itemName}>Email </Text>
<TextInput
style={styles.textInput}
keyboardType={'email-address'}
onChangeText={(email) => this.setState({user_email: email})}
value={this.state.user_email}
/>
</View>
<View style={styles.InformationBox}>
<Text style={styles.itemName}>City </Text>
<TextInput
style={styles.textInput}
onChangeText={(city) => this.setState({user_city: city})}
value={this.state.user_city}
/>
</View>
<View style={styles.InformationBox}>
<Text style={styles.itemName}>Change password </Text>
<TextInput
style={styles.textInput}
defaultValue={"*****"}
onChangeText={(new_password) => this.setState({user_change_password: new_password})}
/>
</View>
<Button
title={"Save Changes"}
onPress={() => this.uploadDataToFirebase()}/>
</View>
</KeyboardAvoidingView>
<View>
<Button
title={"Logout"}
onPress={() => this.signUserOut()}
/>
</View>
</View>
)
}
}
//TODO move this to the styleSheet package.
export default GlobalAccount;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
imageView: {
height: 200,
width: 200,
paddingBottom: 20,
},
image: {
flex: 1,
borderRadius: 10,
},
describtionText: {
fontSize: 20,
},
textInput: {
width: "90%",
},
InformationBox: {
flexDirection: 'row',
width: "80%",
borderWidth: 1,
borderRadius: 10,
borderColor: "gray",
backgroundColor: "orange",
maxHeight: 50,
minHeight: 50,
flex: 1,
},
itemName: {
// flex: 1,purple
width: "30%",
paddingLeft: 5,
paddingTop: 5,
}
});