0

I have the following script

    let link = ""
    let baseUrl = "Test-Dataset/"
    let imageRef = "2.jpg"

    storage.ref(baseUrl + imageRef).getDownloadURL().then(
      function(url) {
      link = url
      console.log(url)
    }).catch(function(error) {
    });

    console.log(link)

My goal is to update the link variable with the value of the image's URL after I use the getDownloadURL() to return a promise and wait for it to be resolved. The console.log function within the .this() is outputting exactly what I need - the link to the image in my firebase storage. However, the console.log outside of the function is returning the initial value of link before the call to my firebase storage was made, which is just "". Why does this happen? Is my solution to make something like the asynchronous function outlined in https://stackoverflow.com/a/53578626/8849802?

Details: I'm using vue and the npm library firebase

Aditya Mehrotra
  • 323
  • 1
  • 18

1 Answers1

1

This happens because your console statement runs before the promise resolves. It has nothing to do with Firebase.

This is what happens:

  1. The link variable is declared with an empty string.
  2. A handler function is added to the promise: .then(function(url) { ... } )
  3. console.log(link) outputs the value of link which is still an empty string
  4. The promise resolves and sets link to url.

Try to add this at the very end of your code to see the effect more clearly:

setTimeout(() => {
  console.log(link);
}, 1000);

This will output the value of link after 1 second. Its value should be the URL you wanted.

To solve the issue, you can use async/await.

const getLink = async (ref) => {
  const url = await storage.ref(ref).getDownloadURL();

  return url;
}

// NB: A function that uses `await` must be `async`
// So, whichever function uses getLink() must be async

function async someFunction() { // Maybe a Vue method?
  const url = await getLink(baseUrl + imageRef);
  console.log(url);
}

To add error handling, use a try/catch block:

function async someFunction() {
  try {
    const url = await storage.ref(baseUrl + imageRef).getDownloadURL();
    console.log(url); // This won't run if getting the URL failed
  } catch (error) {
    // Handle the error
  }
}
nicoqh
  • 1,213
  • 12
  • 21