capacitor-plugins icon indicating copy to clipboard operation
capacitor-plugins copied to clipboard

downloadFile directory default value is incorrect

Open jcesarmobile opened this issue 1 year ago • 4 comments

Bug Report

Plugin(s)

filesystem

Capacitor Version

5

Platform(s)

all

Current Behavior

directory is documented as

  /**
   * The directory to write the file to.
   * If this option is used, filePath can be a relative path rather than absolute.
   * The default is the `DATA` directory.
   *
   * @since 5.1.0
   */
  directory?: Directory;

but on iOS the default is DOCUMENTS. on Android the default is not one of the known directories, but Environment.DIRECTORY_DOWNLOADS. on web the file is not saved into any directory of the Filesystem, but it downloads the actual file

Expected Behavior

The docs should be updated to document the actual behavior, or the code should be adjusted to match the documented behavior.

Code Reproduction

Other Technical Details

Additional Context

jcesarmobile avatar Aug 03 '23 16:08 jcesarmobile

This issue has been labeled as type: bug. This label is added to issues that that have been reproduced and are being tracked in our internal issue tracker.

ionitron-bot[bot] avatar Aug 03 '23 16:08 ionitron-bot[bot]

With the current default on Android, it is not possible to use an absolute path, which is a serious limitation.

That is because to use an absolute path, directory must be null but if directory: null is passed in the options, the default of Environment.DIRECTORY_DOWNLOADS is used.

matleh avatar Nov 23 '23 21:11 matleh

I use an ugly work-around:

async function downloadFile({ url, path, directory }) {
  const postfix = Math.random().toString(36).substring(2);
  let tmpPath;
  if (directory === null) {
    // work-around for Capacitor bug - https://github.com/ionic-team/capacitor-plugins/issues/1717
    try {
      const { path: tmpPath } =  await Filesystem.downloadFile({
        url,
        path: `tmp-${postfix}`,
        directory: Directory.Cache,
      });
      return await Filesystem.copy({ from: tmpPath, to: path });
    } finally {
      if (tmpPath) {
        await Filesystem.deleteFile({ path: tmpPath })
      }
    }
  }
  return await Filesystem.downloadFile({ url, path, directory });
}

matleh avatar Nov 23 '23 22:11 matleh

@jcesarmobile @dtarnawsky, this bug is critical. Renders the downloadFile function outright broken on Android 33 and debugging it to find the above took a while.

jpike88 avatar Nov 29 '23 03:11 jpike88