Reputation: 11
I am trying to get the url that getDownloadURL() should return. However it is in fact returning me data like this.
I have manage to display it on the html, however my real purpose is to get the URL, that can be seen on the image I posted, so I can get it and save it on my Firestore Database. However I dont know how to get that value. This is my snipet:
getImgFromServer(imgName: string): string {
let img;
let downloadIMG;
img = firebase.storage().ref("/imgs/" + imgName).getDownloadURL();
let ref= firebase.storage().ref();
const imgRef = ref.child("/imgs/" + imgName);
imgRef.getDownloadURL().then(function(url){
downloadIMG=url;
img = downloadIMG;
console.log("MY URL " + downloadIMG)
})
console.log("img")
console.log(img)
return img
}
When debugging this log, this code prints the URL I want to use:
console.log("MY URL " + downloadIMG)
However this one, prints the data from the image :
console.log(img)
I would like to return the URL alone so I can use it.
EDIT
Now that I am getting the URL I would like to save it on the Cloud Firestore so I can use the URL on the HTML to show the picture. This is the function that store the name of the image:
createPublic(id,img){
this.firestore.doc(`public/${id}`).set({
img,
});
}
With the answer given by Frank, now I can get the URL, so I just use it to take the URL and with the following function, update the document that I have just uploaded.
async updateImg(img,idPubli){
const imgToUpdate= await this.imgServ.getImgFromServer(img);
this.imgServ.updateImgFromServer(imgToUpdate,idPubli)
}
updateImgFromServer(image,id){
this.firestore.doc(`public/${id}`).set({
img:image,
});
}
However it seems that it is not working. I can imagine that this might be because either the image or the document havent been uploaded before the updateImg() is execute, but I am kinda new to async functions so I can't manage to get a solution rigth now.
In case it helps, this are the functions where I upload the image and the function that uploads it.
submit() {
this.imgServ.uploadImage();
this.viewCtrl.dismiss({data});
}
After the dismiss function, I gather all the dataand then call the createPublic() function.
uploadImage() {
this.image = 'movie-' + new Date().getTime() + '.jpg';
let storageRef: any,
parseUpload: any;
return new Promise((resolve, reject) => {
storageRef = firebase.storage().ref('imgs/' + this.image);
parseUpload = storageRef.putString(this.cameraImage, 'data_url');
parseUpload.on('state_changed', (_snapshot) => {
// We could log the progress here IF necessary
// console.log('snapshot progess ' + _snapshot);
},
(_err) => {
reject(_err);
},
(success) => {
resolve(parseUpload.snapshot);
});
});
}
Upvotes: 1
Views: 5075
Reputation: 598817
Since the download URL is generated by a call to the server, it may take some time before it's available. And you can't make the code wait for that value to be available. That's why getDownloadURL()
returns a promise, and then calls its then()
once it got the download URL back from the server. This URL is only available within the callback, because the code after the callback runs before the server has returned the download URL (and thus before the then()
callback was called).
One common approaches is to just pass the promise around, and use its then()
whenever you need the value. So:
const imgRef = ref.child("/imgs/" + imgName);
const downloadUrl = imgRef.getDownloadURL();
...
downloadUrl.then(function(url){
console.log("MY URL " + url)
})
The alternative on modern environments is to use the new async
/await
keywords. These wrap the promise-based approach of above in some syntactic sugar:
async getImgFromServer(imgName: string): string {
let img;
let downloadIMG;
img = firebase.storage().ref("/imgs/" + imgName).getDownloadURL();
let ref= firebase.storage().ref();
const imgRef = ref.child("/imgs/" + imgName);
const downloadURL = await imgRef.getDownloadURL()
return downloadURL
}
Which you then call as:
const downloadURL = await getImgFromServer("image name")
Also see:
Upvotes: 1