Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");
            }
          );
        }
      }
like image 989
Fransisco Wijaya Avatar asked Nov 05 '18 14:11

Fransisco Wijaya


1 Answers

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...
like image 93
zylo Avatar answered Oct 01 '22 17:10

zylo