4

Need help in getting the resize image URL after the Firebase extension resizes the image.

Before I was able to do so with the code below. But, after activating the function, images are not showing up. After comparing the imgURL on Firestore and the download URL on Firebase storage, it seems that the functions added image dimensions (500x500) to the back of the pathname. (image_123 -> image_123_500x500).

  1. I've tried looking up on how I can exclude that on the Firebase Extension settings. But no luck. (Might miss it)

  2. I figure that the next option is to just tweak the code itself by getting the URL after the image resized. But I'm either getting undefined or error. Plus I can't figure out implementing without creating two separate functions by "Upload the image first" then "Submit Form".

      upload($event: any) {
        this.file = $event.target.files[0];
        this.image = true;
      }


        async submitHandler() {
        if (this.image === true) {
          // Generate random ID
          const randomId = Math.random().toString(36).substring(2);
          // The storage path
          const path = `products/${this.productForm.value.model}_${randomId}`;
          // Reference to storage bucket
          const ref = this.afStorage.ref(path);
          // The main task (upload Image to Firestorage)
          this.task = this.afStorage.upload(path, this.file);
    
          // Get the URL from ref (Firestorage), added to the form and submit to FIrestore
          this.task
            .snapshotChanges()
            .pipe(
              finalize(async () => {
                this.downloadURL = await ref.getDownloadURL().toPromise();
                /*this.afs
                .collection('products')
                .add({ downloadURL: this.downloadURL, path });*/
                this.loading = true;
                this.productForm.value.imgUrl = this.downloadURL;
                this.productForm.value.user = this.auth.getUserEmail();
                const formValue = this.productForm.value;
                try {
                  await this.afs.collection('products').add(formValue);
                  console.log(formValue);
                  this.success = true;
                } catch (err) {
                  console.error(err);
                }
              })
            ) // To display URL
            .subscribe();
    
          this.loading = false;
        } else {
          alert('Please upload the picture of product');
        }
      }
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
syahiruddin
  • 401
  • 5
  • 14
  • what did you end up doing just settimeout to call downloadImageUrl? – EmreAkkoc Jun 13 '23 at 18:32
  • 1
    @EmreAkkoc, this is an excellent question. While Firebase provides some solutions, there might be room for improvement. One approach you could consider is utilizing RXJS operators such as debounceTime or takeUntil, which can enhance the functionality you're looking for. – syahiruddin Jun 30 '23 at 10:37

1 Answers1

3

Indeed, the Resize Image extension will add the height and width to the name of the file, as stated in the official documentation here. As clarified in this answer here, once you installed the extension, it asked you to provide a path for where the files resized will be stored. So, for you to return the downloadURL, it will depend on the name you add for the path or if you didn't add any.

For this reason, you will need to reference the file from the path you set when installing the extension. You will need then, to work on the name of the file, based in the size you set for the new dimensions. You can try following in a way you will add the dimensions to the name of the file. The below code is based in this answer here, that I believe that should help you as a starting point.

function resizedName(fileName, dimensions = '500x500') {
  const extIndex = fileName.lastIndexOf('.');
  const ext = fileName.substring(extIndex);
  return `${fileName.substring(0, extIndex)}_${dimensions}${ext}`;
}

To summarize, you will need to work on the new path to return the files there and in case they are in the same path as the original ones, you will need to modify the name of them, adding the width and height to the names.

gso_gabriel
  • 4,199
  • 1
  • 10
  • 22
  • 1
    Hi, thank you for your answer. I understand that I need to create a new path with the dimension e.g "_500x500" extension at the end of the path, to reference it when calling the resized image `.getDownloadURL()`. But I can't do it all one call function, because the image is not ready and getting error like `code_":"storage/object-not-found"`. My temporary solution currently is to split the funcions by using `(change)="upload"` to upload the image on change first, so by then, the image will be ready to be called when submitting the form with the new reference. I find this clunky solution. – syahiruddin Oct 05 '20 at 14:06
  • 1
    Hi @imcodean sure, I understand your point. Indeed, this ideally wouldn't be the best way, but considering your use case, I believe it's the best way for you to achieve the return of the images via new URL. – gso_gabriel Oct 06 '20 at 06:11