skip to Main Content

I’m using Firebase 10.8.0, developing locally with the emulator suite. I have a cloud function that generates an zip file, and now I’m attempting to build a client function that downloads the file to their local drive.

Here’s what I’ve tried..

const handleDownload = () => {
  // Call the downloadPosts() endpoint
  // This cloud function creates the .zip file
  // The path to the file is returned in the response
  downloadPosts({ authorId: userId, includeTrashedPosts: includeTrashed })

    // Get the response
    // Call getBlob() to download the file
    .then((response) => {
      const { filepath } = response.data
      const fileRef = ref(storage, filepath)
      return getBlob(fileRef, 100000)
    })
    .then((blob) => {
      const url = URL.createObjectURL(blob)
      window.location.replace(url)
    })
}

When I run this function, I’m simply redirected to a web page that looks like this

enter image description here

I have read the docs here and tried to follow this example.

Additionally, here is my file in the Storage console of the Emulator Suite. I am able to download it manually from here.

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    I solved it, kind of. Changing getBlob(fileRef, 100000) to getBlob(fileRef) made it work properly.


  2. It sounds like fetching the entire blob solved your problem, but you may want to use an anchor element to download the file instead of window.location.replace. The advantages are it 1) allows you to name the file, and 2) doesn’t redirect your page, just in case if the server returns an incomplete or nonzip file.

    It looks something like:

      const url = URL.createObjectURL(blob)
      let a = document.createElement('a')
      a.download = 'filename.zip'
      a.href = url
      a.click()
    

    Altogether:

    const handleDownload = () => {
      // Call the downloadPosts() endpoint
      // This cloud function creates the .zip file
      // The path to the file is returned in the response
      downloadPosts({ authorId: userId, includeTrashedPosts: includeTrashed })
    
        // Get the response
        // Call getBlob() to download the file
        .then((response) => {
          const { filepath } = response.data
          const fileRef = ref(storage, filepath)
          return getBlob(fileRef, 100000)
        })
        .then((blob) => {
          const url = URL.createObjectURL(blob)
          let a = document.createElement('a')
          a.download = 'filename.zip'
          a.href = url
          a.click()
          // may want need to put this in a timeout if the blob is too big:
          window.URL.revokeObjectURL(url)
        })
    }
    

    See also:

    https://stackoverflow.com/a/19328891/

    Download File Using JavaScript/jQuery (A lot of the answers append the anchor element to the body, but from my experience, you don’t actually have to attach it to DOM)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search