I have an app to connect user and I have a problem to upload images and put download url in database.
I'm using:
- Node: 12.9.1
- Yarn: 1.13.0
- npm: 6.10.2
- react-native-cli: 2.0.1
- react-native: 0.60.5
I will put my code here:
import React, {useState} from 'react';
import {
View,
ImageBackground,
Image,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
ScrollView,
AsyncStorage,
Platform,
} from 'react-native';
import {Avatar} from 'react-native-elements';
import ImagePicker from 'react-native-image-picker';
import RNFetchBlob from 'react-native-fetch-blob';
import firebaseApp from '../config/firebaseConfig';
import background from '../assets/background.png';
import logo from '../assets/logo.png';
const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;
export default class Logon extends React.Component {
constructor(props) {
super(props);
this.state = {
userID: null,
email: '',
password: '',
name: '',
surname: '',
birthdate: null,
picture: null,
title: '',
nickname: '',
errorMessage: null,
city: '',
};
}
render() {
return (
<ImageBackground style={styles.background} source={background}>
<View style={styles.container}>
<Image style={styles.logo} source={logo} />
<View style={styles.formContainer}>
<ScrollView>
<View style={styles.iconContainer}>
<Avatar
size="xlarge"
rounded
title="GS"
source={{uri: this.state.picture}}
activeOpacity={0.7}
onPress={() => this.handlePicture()}
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputText}>Email: </Text>
<TextInput
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
placeholder="email@email.com"
placeholderTextColor="#999"
onChangeText={email => this.setState({email})}
style={styles.input}
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputText}>Senha: </Text>
<TextInput
secureTextEntry={true}
autoCapitalize="none"
autoCorrect={false}
onChangeText={password => this.setState({password})}
style={styles.input}
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputText}>Nome: </Text>
<TextInput
style={styles.input}
onChangeText={name => this.setState({name})}
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputText}>Sobrenome: </Text>
<TextInput
style={styles.input}
onChangeText={surname => this.setState({surname})}
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputText}>Nickname: </Text>
<TextInput
style={styles.input}
onChangeText={nickname => this.setState({nickname})}
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.sendButton}
onPress={() => this.handleLogon()}>
<Text style={styles.sendButtonText}>Enviar</Text>
</TouchableOpacity>
</View>
{/* {this.renderErrorMessage()} */}
<View style={styles.logonContainer}>
<Text style={styles.logonText}>Já tens a tua conta?</Text>
<TouchableOpacity onPress={() => this.handleLogin()}>
<Text style={styles.logoButtonText}>Clica aqui</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
</View>
</ImageBackground>
);
}
handleLogin = () => {
this.props.navigation.navigate('Login');
};
handlePicture = () => {
ImagePicker.showImagePicker(options, response => {
if (response.didCancel) {
return;
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
this.setState({
picture: response.uri,
});
}
});
};
handleLogon = async () => {
await firebaseApp
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then(userData => {
uploadImage(userData.user.uid);
});
};
}
export const uploadImage = (userId, mime = 'application/octet-stream') => {
return dispatch => {
return new Promise((resolv, reject) => {
const uri = () => {
this.state.picture;
};
const uploadUri =
Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
let uploadBlob = null;
const imageRef = firebaseApp
.storage()
.ref('users')
.child(userId);
fs.readFile(uploadUri, 'base64')
.then(data => {
return Blob.build(data, {type: `${mime};BASE64`});
})
.then(blob => {
uploadBlob = blob;
return imageRef.put(blob._ref, blob, {contentType: mime});
})
.then(() => {
uploadBlob.close();
return imageRef.getDownloadURL();
})
.then(url => {
resolv(url);
console.log(url);
storeReference(url, userId);
})
.catch(error => {
reject(error);
});
});
};
};
const storeReference = (downloadUrl, sessionId) => {
const data = {
ID: sessionId,
email: this.state.email,
name: this.state.name,
surname: this.state.surname,
nickname: this.state.nickname,
picture: downloadUrl,
};
firebaseApp
.database()
.ref('users/' + sessionId)
.set(data);
};
const options = {
title: 'Select Avatar',
takePhotoButtonTitle: 'Capturar foto',
chooseFromLibraryButtonTitle: 'Escolher da galeria',
storageOptions: {
skipBackup: true,
path: 'GameSolv',
},
};
const styles = StyleSheet.create({
background: {
width: '100%',
height: '100%',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
logo: {
width: 500,
height: 150,
top: 20,
},
formContainer: {
flex: 1,
width: '80%',
paddingTop: 70,
},
iconContainer: {
alignItems: 'center',
paddingBottom: 20,
},
inputContainer: {
paddingBottom: 20,
},
inputText: {
color: '#FFF',
fontSize: 16,
letterSpacing: 3,
},
email: {
height: 46,
alignSelf: 'stretch',
backgroundColor: '#FFF',
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 4,
marginTop: 0,
paddingHorizontal: 15,
},
input: {
height: 46,
alignSelf: 'stretch',
backgroundColor: '#FFF',
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 4,
marginTop: 0,
paddingHorizontal: 15,
},
sendButton: {
marginTop: 20,
marginBottom: 30,
width: 200,
height: 45,
backgroundColor: '#FFF',
borderRadius: 5,
justifyContent: 'center',
alignItems: 'center',
},
buttonContainer: {
alignItems: 'center',
},
sendButtonText: {
fontSize: 30,
fontWeight: 'bold',
color: '#622980',
letterSpacing: 7,
fontFamily: 'Roboto-Light',
},
logonContainer: {
alignItems: 'center',
paddingBottom: 20,
},
logonText: {
color: '#FFF',
fontSize: 16,
letterSpacing: 3,
},
logoButtonText: {
color: '#fcef21',
fontSize: 16,
letterSpacing: 3,
textDecorationLine: 'underline',
},
});
Image with the error
It says:
Attempt to invoke interface method 'java.lang.String com.facebook.react.bridge.ReadableMap.getString(java.lang.String)' on a null object reference