I need this general purpose utility method that accepts the file object and return me the url of the file after uploading, but some how I am getting a promise instead of the download URL.
I have tried all approached, i need ES6 async/await
solution.
export const uploadFile = (file) => {
let uploadTask = storage.ref(`products/${Date.now()}.${file.name.split('.').pop()}`).put(file);
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, {
'complete': () => {
uploadTask.snapshot.ref.getDownloadURL().then((d) => {
return d
})
}
});
}
As explained in the doc, if you call then()
on a UploadTask
, you will get an object which "behaves like a Promise, and resolves with its snapshot data when the upload completes".
Therefore the following should do the trick.
export const uploadFile = (file) => {
let uploadTask = storage.ref(`products/${Date.now()}.${file.name.split('.').pop()}`).put(file);
return uploadTask.
then(snapshot => {
return snapshot.ref.getDownloadURL();
})
.then((url) => {
return url
});
}
Update following your comment:
You mention in the comments that you call the function as follows:
let files = state.images;
for (let i = 0; i < e.target.files.length; i++) {
files = files.concat(e.target.files[i]);
let url = uploadFile(files[i])
console.log(url)
}
However, the uploadFile()
function is asynchronous and indeed, as a consequence, it returns a Promise. You should take that into account when calling it. For example, with a loop, you could call it as follows:
const promises = [];
let files = state.images;
for (let i = 0; i < e.target.files.length; i++) {
files = files.concat(e.target.files[i]);
promises.push(uploadFile(files[i]));
}
Promise.all(promises)
.then(urlsArray => {
urlsArray.forEach(url => {
console.log(url);
})
})