Fransisco Wijaya
Fransisco Wijaya

Reputation: 397

Async/Await uploadTask

How can I await uploadTask so I can upload the image/file and track its progress first before inserting download url dan document to firestore,

Following code is my sample Vue project. It works properly, but see the if (portraitFile), it has to be within the condition that I have to upload an image, what if I don't want to upload an image?

It has to move outside that conditional if, but it will executed asynchronously before the file finish and download URL retrieved.

GOAL: Move firestore add() outside uploadTask's finish callback/argument.

    async commitCharacter() {
      try {
        let character = this.character;
        let portraitFile = this.portraitFile;

        if (portraitFile) {
          const uploadTask = storageRef
            .child(`characters/${character.id}/portrait.png`)
            .put(portraitFile, { contentType: "image/png" });

          await uploadTask.on(
            "state_changed",
            snapshot => {
              this.portraitUploadProgress =
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            },
            null,
            async () => {
              character.portraitUrl = await storageRef
                .child(`characters/${character.id}/portrait.png`)
                .getDownloadURL();

              if (character.id) {
              await db
                .collection("characters")
                .doc(character.id)
                .update(character);
              } else {
                character.id = (await 
                db.collection("characters").add(character)).id;
              }

              $("#manageCharacter").modal("hide");
            }
          );
        }
      }

Upvotes: 11

Views: 2507

Answers (1)

8ctopotamus
8ctopotamus

Reputation: 518

You can wrap your uploadTask in a promise:

async function uploadTaskPromise() {
  return new Promise(function(resolve, reject) {
    const storageRef = storage.ref(YOUR_STORAGE_PATH)
    const uploadTask = storageRef.put(YOUR_FILE_OR_BLOB)
    uploadTask.on('state_changed',
      function(snapshot) {
        var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
        console.log('Upload is ' + progress + '% done')
      },
      function error(err) {
        console.log('error', err)
        reject()
      },
      function complete() {
        uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
          resolve(downloadURL)
        })
      }
    )
  })
}

And then use it like this:

const storageUrl = await uploadTaskPromise()
console.log(storageUrl) // do whatever you want with the URL...

Upvotes: 21

Related Questions