ionic-team / ionic-team/capacitor-file-transfer

Android: downloadFile requests storage permission for app-private file paths

Open
#72 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
11
Forks
10
PR merge metrics
No merged PRs in 30d

Description

### Description

On Android < 30, `FileTransfer.downloadFile()` appears to require public storage permission even when the destination is an app-private `file://` path under the app data directory.

In our Capacitor app, downloading a ~21 MB SQLite metadata snapshot to an app-private path failed almost immediately on Android 9/10 with:

```text
Error during file transfer
```

The same download succeeds when using deprecated `Filesystem.downloadFile()` with `directory: Directory.Data`, which only checks storage permission for public directories.

### Reproduction shape

```ts
const path = `tmp/data.sqlite`
await Filesystem.mkdir({ path: `tmp`, directory: Directory.Data, recursive: true })
const { uri } = await Filesystem.getUri({ path, directory: Directory.Data })

// Fails quickly on Android < 30 due to storage permission path
await FileTransfer.downloadFile({ url, path: uri })

// Works; writes to app-private storage
await Filesystem.downloadFile({
url,
path,
directory: Directory.Data,
recursive: true,
})
```

### Expected behavior

`FileTransfer.downloadFile()` should not require public/external storage permission when the destination is app-private storage, or it should provide an option/API shape equivalent to `Filesystem.downloadFile({ directory: Directory.Data })`.

### Versions

- `@capacitor/core`: `^8.3.1`
- `@capacitor/file-transfer`: `^2.0.4`
- `@capacitor/filesystem`: `^8.1.2`
- Observed on Android 9/10; API 28 repro confirmed.

Contributor guide

Open the contributing guide

Research direction

Start at the FileTransfer.downloadFile() entry point and compare its Android permission handling with Filesystem.downloadFile({ directory: Directory.Data }). Reproduce the app-private download on Android 9 or API 28, then verify that private destinations work without public storage permission while public storage behavior remains correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, typescript
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.