15
votes

I am trying to upload a single image to Firebase Storage, then grab its download url and assign this to a variable.

I can upload my image to firebase successfully, however I cannot retrieve the download url. here is what I have tried already.

upload() {
    let storageRef = firebase.storage().ref();
    let success = false;

    for (let selectedFile of [(<HTMLInputElement>document.getElementById('file')).files[0]]) {
      let router = this.router;
      let af = this.af;
      let folder = this.folder;
      let path = `/${this.folder}/${selectedFile.name}`;
      var iRef = storageRef.child(path);
      iRef.put(selectedFile).then((snapshot) => {
        console.log('Uploaded a blob or file! Now storing the reference at', `/${this.folder}/images/`);
        af.list(`/${folder}/images/`).push({ path: path, filename: selectedFile.name })
      });
    }

    // This part does not work
    iRef.getDownloadURL().then((url) => {this.image = url});
    console.log('IREF IS ' + iRef)
    console.log('IMAGEURL IS ' + this.image)

  }

The Console logs are these:

    IREF IS gs://my-app-159520.appspot.com/images/Screen Shot 2017-08-14 at 12.19.01.png
    view-order.component.ts:134 IMAGEURL IS undefined
Uploaded a blob or file! Now storing the reference at /images/images/

I have been trying to use the iRef reference to grab the download url but I keep getting errors. I am trying to grab the url so I can assign it to the this.image variable and then store it in my database using another function.

4
Where is image defined?, and why it is undefined?onetwo12
Image is defined at the top above the constructor as image:anyBrian Revie
I think I may have figured it out, will update original post.Brian Revie
Great to hear that you found the solution Brian. Can you post that as an answer? On Stack Overflow it is acceptable to self-answer, since it doesn't really matter who answered your question as long as it was addressed.Frank van Puffelen
certainly @FrankvanPuffelen :)Brian Revie

4 Answers

15
votes

The API has changed. Use the following to get downloadURL

  snapshot.ref.getDownloadURL().then(function(downloadURL) {
    console.log("File available at", downloadURL);
  });
5
votes

I think I have figured this out and it seems to be working, I realised I had to grab the downloadURL from the snapshot and assign that to this.image like so:

upload() {
    let storageRef = firebase.storage().ref();
    let success = false;

    for (let selectedFile of [(<HTMLInputElement>document.getElementById('file')).files[0]]) {
      let router = this.router;
      let af = this.af;
      let folder = this.folder;
      let path = `/${this.folder}/${selectedFile.name}`;
      var iRef = storageRef.child(path);
      iRef.put(selectedFile).then((snapshot) => {

        // added this part which as grabbed the download url from the pushed snapshot
        this.image = snapshot.downloadURL;

        console.log('Uploaded a blob or file! Now storing the reference at', `/${this.folder}/images/`);
        af.list(`/${folder}/images/`).push({ path: path, filename: selectedFile.name })

        console.log('DOWNLOAD URL IS ' + this.image)
      });
    }

  }

I then ran my other function to add the URL to the database and it has gone in ok where expected!

So I have uploaded the image to the database, then using the snapshot from the put function, I then assigned my variable image:any to to the snapshot downloadURL like so:

this.image = snapshot.downloadURL;

I hope this can help someone else!

4
votes

.put() function is returning a task, which can be used to track the uploading state.

For example you can listen for progress, error or completion like so:

onUploadImage () {
  const self = this
  const file = self.selectedFile
  if (!file) {
    return
  }
  self.isUploading = true
  const storageRef = firebase.storage().ref('/images/' + file.name)
  const task = storageRef.put(file)
  task.on('state_changed',
    function progress (snapshot) {
      self.status = 'UPLOADING...'
      self.percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
    },
    function error () {
      self.status = 'FAILED TRY AGAIN!'
      self.isUploading = false
    },

    function complete (event) {
      self.status = 'UPLOAD COMPLETED'
      self.isUploading = false
      storageRef.getDownloadURL().then((url) => { console.log(url) })
    }
  )
}
3
votes

In 2019, I gained access to the url of a newly-saved file in firebase with the following function:

const uploadImage = async(uri) => {
  const response = await fetch(uri);
  const blob = await response.blob();
  // child arg specifies the name of the image in firebase
  const ref = firebase.storage().ref().child(guid());
  ref.put(blob).then(snapshot => {
    snapshot.ref.getDownloadURL().then(url => {
      console.log(' * new url', url)
    })
  })
}