I want to upload an image to firebase (which is working), then return the download URL of the image and store it as a string.
Here is my code:
uploadImage = async (uri, imageName) => {
const response = await fetch(uri);
const blob = await response.blob();
firebase.storage().ref().child(imageName).put(blob)
.then(snap => {
return snap.ref.getDownloadURL();
})
.then(downloadURL => {
return downloadURL;
})
.catch(error => {
console.log(`An error occurred while uploading the file.\n\n${error}`);
});
}
The image uploads to firebase storage just fine. At the moment it just shows this when I try write the URL of the uploaded image to the database: https://ibb.co/WHHHxBY
Here is the block of code where I create the user record:
firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then(userCredentials => {
let imageUrl = '';
let db = firebase.database().ref('users/' + userCredentials.user.uid);
if (this.state.image) {
imageUrl = this.uploadImage(this.state.image.uri, `images/user-${userCredentials.user.uid}`);
}
db.set({
email: this.state.email,
imageUrl: imageUrl,
username: this.state.username
});
return userCredentials.user.updateProfile({
displayName: this.state.username
});
})
.catch(error => this.setState({ errorMessage: error.message }));
In your uploadImage
function, you are chaining the promises but you don't return the chain. You should adapt it as follows:
uploadImage = async (uri, imageName) => {
const response = await fetch(uri);
const blob = await response.blob();
return firebase.storage().ref().child(imageName).put(blob) // <-- Here return the chain
.then(snap => {
return snap.ref.getDownloadURL();
})
.then(downloadURL => {
return downloadURL;
})
.catch(error => {
console.log(`An error occurred while uploading the file.\n\n${error}`);
});
}
However, you could transform this code in async/await
"style", as follows:
uploadImage = async (uri, imageName) => {
try {
const response = await fetch(uri);
const blob = await response.blob();
const snap = await firebase.storage().ref().child(imageName).put(blob);
const downloadURL = await snap.ref.getDownloadURL();
return downloadURL;
} catch (e) {
console.error(e);
throw e;
}
}
Then, since this uploadImage
function is asynchronous you should adapt the way you call it. I suggest to modify the other part of your code as follows:
try {
const userCredentials = await firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password);
let imageUrl = '';
const db = firebase.database().ref('users/' + userCredentials.user.uid);
if (this.state.image) {
imageUrl = await this.uploadImage(this.state.image.uri, `images/user-${userCredentials.user.uid}`);
await db.set({
email: this.state.email,
imageUrl: imageUrl,
username: this.state.username
});
return userCredentials.user.updateProfile({
displayName: this.state.username
});
}
//You should probably manage the else case
} catch (e) {
this.setState({ errorMessage: e.message })
}