如何解决图片上传无法显示在图片位置
我正在 react-native expo 上开发一个应用程序,我已经创建了一个用户注册,用户可以在其中上传要显示在用户个人资料上的照片,什么工作完美,但现在我正在尝试创建一个更新注册时设置的用户信息,我可以在个人资料上显示用户的所有字段,但也许我缺少更新的内容,当我尝试获取新图像时,它没有显示,希望其他人可以看到我无法显示和更新这些字段的内容。 此外,在我尝试更新用户信息后,还有一个黄色的早晨错误:
[Unhandled promise rejection: FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string,but it was: undefined]
这是 Register.js 代码:
import { StatusBar } from 'expo-status-bar';
import Fire from '../../Fire';
import React from 'react';
import { Image,StyleSheet,Text,View } from 'react-native';
import { TextInput,TouchableOpacity } from 'react-native-gesture-handler';
import { Ionicons } from 'react-native-vector-icons';
import UserPermissions from '../../utilities/UserPermissions';
import * as ImagePicker from 'expo-image-picker';
export default class RegisterScreen extends React.Component {
static navigationOptions = {
headerShown: false
};
state = {
user: {
name: '',state: '',city: '',email: '',password: '',confirmPassword: '',profilePhotoUrl: null
},errorMessage: null,};
handlePickProfilePhoto = async () => {
UserPermissions.getMediaGalleryPermission();
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,allowsEditing: true,aspect: [1,1]
});
if (!result.cancelled) {
this.setState({ user: { ...this.state.user,profilePhotoUrl: result.uri } })
};
};
handleSignUp = () => {
Fire.shared.createUser(this.state.user);
};
render() {
if (!this.state.user.password === this.state.user.confirmPassword) {
alert("Passwords don't match");
return;
} else if (this.state.user.name === '' || this.state.user.state === '' ||
this.state.user.city === '' || this.state.user.email === '' ||
this.state.user.password === '' || this.state.user.confirmPassword === '' ) {
alert("All fields must be filled up");
return;
};
return (
<View style={styles.container}>
<StatusBar barStyle='light-content' />
<View
style={{ top: 5,alignItems: 'center',width: '100%' }}>
<Text style={styles.greating}>
{'Welcome aboard.\nSign up to get startd'}
</Text>
<TouchableOpacity style={styles.profilePhotoPlaceholder}
onPress={this.handlePickProfilePhoto}>
<Image
source={{ uri: this.state.user.profilePhotoUrl }}
style={styles.profilePhoto}
/>
<Ionicons
name='ios-add-circle-outline'
size={150} color='#fff'
style={{ marginTop: 1,marginLeft: -10 }}
/>
</TouchableOpacity>
</View>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.errorMessage}>
{this.state.errorMessage}
</Text>}
</View>
<View style={styles.form}>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>Full Name</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
onChangeText={name => this.setState({ user: {...this.state.user,name} })}
value={this.state.user.name}
/>
</View>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>State of residence</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
onChangeText={state => this.setState({ user: {...this.state.user,state} })}
value={this.state.user.state}
/>
</View>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>City of residence</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
onChangeText={city => this.setState({ user: {...this.state.user,city} })}
value={this.state.user.city}
/>
</View>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>Email Address</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
onChangeText={email =>
this.setState({ user: {...this.state.user,email} })}
value={this.state.user.email}
/>
</View>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>Password</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
secureTextEntry={true}
onChangeText={password =>
this.setState({ user: {...this.state.user,password} })}
value={this.state.user.password}
/>
</View>
<View style={{ marginTop: 5 }}>
<Text style={styles.inputTitle}>Confirm Password</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
secureTextEntry={true}
onChangeText={confimrPassword =>
this.setState({ user: {...this.state.user,confimrPassword} })}
value={this.state.user.confimrPassword}
/>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleSignUp}>
<Text style={{ color: '#fff',fontWeight: '500' }}>Sign up</Text>
</TouchableOpacity>
<TouchableOpacity style={{ alignSelf: 'center',}}>
<Text
style={{ color: '#fff',fontSize: 13 }}
onPress={() => this.props.navigation.navigate('Login')}
>
Already Begrato? <Text style={{ color: '#ff2222',fontWeight: '500' }}>
Login
</Text>
</Text>
</TouchableOpacity>
</View>
);
};
};
const styles = StyleSheet.create({
container: {
flex: 1,backgroundColor: '#263237',},greating: {
color: '#ffffffdd',marginTop: 6,fontSize: 18,fontWeight: '400',textAlign: 'center'
},errorMessage: {
color: '#ff222266',height: 72,justifyContent: 'center',marginHorizontal: 30
},error: {
color: '#e9446a',fontSize: 13,fontWeight: '600',textAlign: 'center',form: {
marginBottom: 48,marginHorizontal: 30,inputTitle: {
color: '#156cc5',fontSize: 10,textTransform: 'uppercase',input: {
borderBottomColor: '#ff2222',borderBottomWidth: StyleSheet.hairlineWidth,height: 25,fontSize: 15,color: '#7cdcfe'
},button: {
marginBottom: 25,backgroundColor: '#e9446a',borderRadius: 4,height: 52,back: {
top: -10,position: 'relative',left: 10
},profilePhoto: {
position: 'absolute',width: 120,height: 120,borderRadius: 50,profilePhotoPlaceholder: {
width: 120,backgroundColor: '#e1e2e6',marginTop: 10,});
这是我正在处理的 Profile.js 代码:
import React,{ useState,useEffect } from 'react';
import {
Button,Image,View,FlatList,Modal,TextInput } from 'react-native';
import styled from 'styled-components';
import * as ImagePicker from 'expo-image-picker';
import UserPermissions from '../../utilities/UserPermissions';
import { Feather } from 'react-native-vector-icons';
import firebase from 'firebase';
require('firebase/firestore');
import { connect } from 'react-redux';
function Profile(props) {
const [userPosts,setUserPosts] = useState([]);
const [user,setUser] = useState(null);
const [open,setOpen] = useState(false);
const [hasMediaLibraryPermission,setHasMediaLibraryPermission] = useState(null);
const [profilePhotoUrl,setProfilePhotoUrl] = useState(user?.profilePhotoUrl);
const [name,setName] = useState(user?.name);
const [state,setState] = useState(user?.state);
const [city,setCity] = useState(user?.city);
const [email,setEmail] = useState(user?.email);
useEffect(() => {
const { currentUser,posts } = props;
(async () => {
const mediaLibraryStatus = await ImagePicker.requestMediaLibraryPermissionsAsync();
setHasMediaLibraryPermission(mediaLibraryStatus.status === 'granted');
})();
if (props.route.params.uid === firebase.auth().currentUser.uid) {
setUser(currentUser)
setUserPosts(posts)
} else {
firebase.firestore()
.collection('users')
.doc(props.route.params.uid)
.get()
.then((snapshot) => {
if (snapshot.exists) {
setUser(snapshot.data());
}
else {
console.log('does not exist')
}
})
firebase.firestore()
.collection('posts')
.doc(props.route.params.uid)
.collection('userPosts')
.orderBy('creation','desc')
.get()
.then((snapshot) => {
let posts = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return { id,...data }
})
setUserPosts(posts)
});
};
//content deleted
},[props.route.params.uid]);
// create new upload functions
async function updateProfile(){
if(name === '' || state === '' || city === ''){
return;
}
await firebase.firestore().collection('users')
.doc(user.uid).update({
name: name,state: state,city: city,profilePhotoUrl: profilePhotoUrl
})
//Search for all posts from user
const postDocs = await firebase.firestore().collection('posts')
.where('userId','==',user.uid ).get();
//Search and update names of the user posts
postDocs.forEach( async doc => {
await firebase.firestore().collection('posts').doc(doc.id).update({
name: name,})
});
let data = {
uid: user.uid,name: name,profilePhotoUrl: profilePhotoUrl,email: user.email,};
setUser(data);
storageUser(data);
setOpen(false);
};
async function handlePickProfilePhoto() {
UserPermissions.getMediaGalleryPermission();
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,1]
});
if (!result.cancelled) {
setProfilePhotoUrl({ user: {...user,profilePhotoUrl: result.uri} });
};
setProfilePhotoUrl(result);
};
// Image upload
const uploadFile = () => {
const options = {
noData: true,mediaType: 'photo'
};
ImagePicker.launchImageLibrary(options,response => {
if(response.didCancel){
console.log('CANCELOU O MODAL.');
}else if(response.error){
console.log('Parece que deu algum erro: ' + response.error);
}else{
uploadFileFirebase(response);
setUrl(response.uri);
}
})
}
const getFileLocalPath = response => {
const { path,uri } = response;
return Platform.OS === 'android' ? path : uri;
};
const uploadFileFirebase = async response => {
const fileSource = getFileLocalPath(response);
const storageRef = storage().ref('users').child(user?.uid);
return await storageRef.putFile(fileSource)
};
const onLogout = () => {
firebase.auth().signOut();
};
if (user === null) {
return <View />
}
return (
<View style={styles.container}>
<View style={{ alignItems: 'center' }}>
<View style={styles.profilePhotoContainer}>
{
user.profilePhotoUrl ?
(
<UploadButton>
<Text style={styles.uploadText}>+</Text>
<Image style={styles.profilePhoto} source={{ uri: user.profilePhotoUrl }} />
</UploadButton>
) :
(
<Image style={styles.profilePhoto}
source={require('../../assets/defaultProfilePhoto.jpg')}
/>
)
}
</View>
</View>
<View style={styles.containerInfo}>
<Text>Usuário: {user?.name}</Text>
<Text>Estado: {user?.state}</Text>
<Text>Usuário: {user?.city}</Text>
<Text>E-mail: {user?.email}</Text>
<View style={{ alignItems: 'center',marginBottom: 10,}}>
<ButtonStyled bg='#428cfd' onPress={() => setOpen(true)}>
<ButtonText color='#fff'>Update Profile</ButtonText>
</ButtonStyled>
</View>
<Modal visible={open} animationType="slide" transparent={true}>
<View style={styles.modalContainer}>
<View style={{ marginTop: 5,marginBottom: 10 }}>
<Button
title='Pick Image From Gallery'
onPress={() => handlePickProfilePhoto()}
/>
<Button
title='Save'
onPress={uploadFile}
/>
</View>
<ButtonBack onPress={() => setOpen(false)}>
<Feather
name="arrow-left"
size={22}
color="#121212"
/>
<ButtonText color="#121212" >Voltar</ButtonText>
</ButtonBack>
<TextInput
placeholder={user?.name}
value={name}
onChangeText={(text) => setName(text)}
/>
<TextInput
placeholder={user?.state}
value={state}
onChangeText={(text) => setState(text)}
/>
<TextInput
placeholder={user?.city}
value={city}
onChangeText={(text) => setCity(text)}
/>
<TextInput
placeholder={user?.email}
value={email}
onChangeText={(text) => setEmail(text)}
/>
<ButtonStyled bg="#428cfd" onPress={updateProfile}>
<ButtonText color="#f1f1f1">Atualizar</ButtonText>
</ButtonStyled>
</View>
</Modal>
<Button
title='Logout'
onPress={() => onLogout()}
/>
</View>
<View style={styles.containerGallery}>
<FlatList
numColumns={3}
horizontal={false}
data={userPosts}
renderItem={({ item }) => (
<View
style={styles.containerImage}>
<Image
style={styles.image}
source={{ uri: item.downloadURL }} // it comes from posts
/>
</View>
)}
/>
</View>
</View>
);
};
const ButtonStyled = styled.TouchableOpacity`
margin-top: 12px;
align-items: center;
justify-content: center;
background-color: ${props => props.bg};
width: 80%;
height: 45px;
border-radius: 5px;
`;
const ButtonText = styled.Text`
font-size: 20px;
color: ${props => props.color};
font-style: italic;
`;
const ButtonBack = styled.TouchableOpacity`
position: absolute;
top: 18px;
left: 25px;
flex-direction: row;
align-items: center;
`;
const UploadButton = styled.TouchableOpacity`
background-color: #fff;
width: 165px;
height: 165px;
border-radius: 90px;
justify-content: center;
align-items: center;
z-index: 5;
`;
const styles = StyleSheet.create({
container: {
flex: 1,containerInfo: {
margin: 20
},containerGallery: {
flex: 1
},containerImage: {
flex: 1 / 3
},image: {
flex: 1,aspectRatio: 1 / 1
},cameraContainer: {
flex: 1,flexDirection: 'row'
},fixedRatio: {
flex: 1,aspectRatio: 1
},modalContainer: {
width: '100%',height: '70%',backgroundColor: '#FFF',position: 'absolute',bottom: 0,input: {
width: '90%',height: 50,backgroundColor: '#DDD',borderRadius: 10,padding: 10,fontSize: 20,profilePhoto: {
width: 160,height: 160,borderRadius: 80,profilePhotoContainer: {
alignItems: 'center',marginTop: '5%',shadowOpacity: 0.8,shadowRadius: 30,shadowColor: '#222'
},errorMessage: {
color: '#ff222266',marginHorizontal: 30
},uploadText: {
zIndex: 1,fontSize: 55,color: '#ff8000',opacity: 0.4
},})
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser,posts: store.userState.posts
})
export default connect(mapStateToProps,null)(Profile);
我不知道还有什么我应该尝试更新这些字段,有
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。