react-native-blob-util icon indicating copy to clipboard operation
react-native-blob-util copied to clipboard

Using Android download manager returns wrong path and empty file

Open pid0r-3blan opened this issue 1 year ago • 16 comments

When I use Android media manager to download file, and then try to use .path() in copyToMediaStore, it fails.

I investigated it a bit and that's what I found.

  1. The file is downloaded succesfully and if I tap on a download notification, I can open it. The path of this file is content://com.android.providers.downloads.ui.fileprovider/cache-path/googlelogo_color_272x92dp-2.png. The file is not visible in Photos app and probably remains somewhere in cache.
  2. The fetch result contains path and it's /data/user/0/com.android.providers.downloads/cache/googlelogo_color_272x92dp-2.png
  3. .base64() of the "fetch" result returns {"_h": 0, "_i": 0, "_j": null, "_k": null} (but this could be not relevant to the issue)
  4. When MediaCollection.copyToMediaStore is called with the .path() mentioned above, it returns No such file '/data/user/0/com.android.providers.downloads/cache/googlelogo_color_272x92dp-2.png'; /data/user/0/com.android.providers.downloads/cache/googlelogo_color_272x92dp-2.png: open failed: ENOENT (No such file or directory)

If I use fetch without addAndroidDownloads option, it works okay and file is saved to media store.

Steps to reproduce:

ReactNativeBlobUtil.config({
  addAndroidDownloads: {
    useDownloadManager: true,
    notification: true, // I know this is by default, just in case
  },
})
  .fetch('GET', 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')
  .then(async res => {
    const path = res.path();
    console.log('path: ', path);
    console.log('base64: ', await res.base64());
    let result = await ReactNativeBlobUtil.MediaCollection.copyToMediaStore(
      {
        name: 'test_file.png', // name of the file
        parentFolder: '', // subdirectory in the Media Store, e.g. HawkIntech/Files to create a folder HawkIntech with a subfolder Files and save the image within this folder
        mime: 'image/png',
      },
      'Download', // Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
      path, // Path to the file being copied in the apps own storage
    );
  });
  • React Native version: 0.71.13
  • react-native-blob-util version: 0.19.1
  • Android: v13, 14 in emulator. Version 11 on a real device

pid0r-3blan avatar Sep 22 '23 13:09 pid0r-3blan

For 3rd point, recheck the .base64() method, you might be printing a promise, just add an await before it.

My problem is with android download manager unable to handle post method requests for download. It just sends a get request without any body.

sanchayIL avatar Sep 23 '23 10:09 sanchayIL

Hi @pid0r-3blan, i have the same issue with pdf files with the same exact scénarios, do you fond a solution to have have a valid file path when useDownloadManager is set to true ?

ZHoussemEddine avatar Oct 19 '23 22:10 ZHoussemEddine

I'm experiencing the same problem, trying to fetch with useDownloadManager set to true and then attempting to copyToMediaStore - which results in the same error described above by @pid0r-3blan. Did anyone find any solution/workaround?

skezzeks avatar Oct 24 '23 11:10 skezzeks

Facing the same issue here, was trying to preview the pdf file after download but hit with error on android

WARN  Possible Unhandled Promise Rejection (id: 10):
Error: Failed to find configured root that contains /data/data/com.android.providers.downloads/cache/sample-18.pdf
ReactNativeBlobUtil.android.actionViewIntent(
            res.path(),
            'application/pdf',
          );

Ref: https://github.com/RonRadtke/react-native-blob-util/issues/40#issuecomment-1846486304

anniewey avatar Dec 08 '23 03:12 anniewey

I have the same issue. Have you come up with a solution for it?

kenneth0417 avatar Dec 13 '23 16:12 kenneth0417

Have the same Error right now. So frustrating..

SalihColak avatar Dec 14 '23 11:12 SalihColak

This issue still exists. Anyone been able to solve it yet?😔

mureyvenom avatar Feb 06 '24 10:02 mureyvenom

Facing same issue

naeem-akhtar-cs avatar Mar 31 '24 10:03 naeem-akhtar-cs

Working path for both platform:

    const {
      dirs: { DownloadDir, DocumentDir },
    } = ReactNativeBlobUtil.fs;
    const fileDirPathAndroid = '/storage/emulated/0/Download';
    const aPath = Platform.select({ ios: DocumentDir, android: fileDirPathAndroid });
    const fPath = `${aPath}/${item?.docName}.${extension}`;

Ajmal0197 avatar Apr 01 '24 08:04 Ajmal0197

Working path for both platform:

    const {
      dirs: { DownloadDir, DocumentDir },
    } = ReactNativeBlobUtil.fs;
    const fileDirPathAndroid = '/storage/emulated/0/Download';
    const aPath = Platform.select({ ios: DocumentDir, android: fileDirPathAndroid });
    const fPath = `${aPath}/${item?.docName}.${extension}`;

Not working on android 14 - Pixel 8 pro simulator

truongnv98 avatar Jul 26 '24 07:07 truongnv98

I'll try to take a look into it in the upcoming week

RonRadtke avatar Jul 27 '24 05:07 RonRadtke

So the problem seems to be that the file belongs to the download Manager and we don't have access to it. So I am gonna add another config to store it within the apps filesystem and might change the implementation for "path" config so it does check and create missing directories.

Hopefully the download manager still can open the file then though

RonRadtke avatar Jul 29 '24 15:07 RonRadtke

I added a new option "stroreLocal". This will save the file to the local download directory. @truongnv98 can you maybe give it a try? On my Pixel 8 real device it worked well now, using the new option (storeLocal) ofc.

RonRadtke avatar Jul 29 '24 21:07 RonRadtke

I was able to fix this issue by setting the Path to ${ReactNativeBlobUtil.fs.dirs.DownloadDir}/${fileName} even though the documentation stated that The destination which the file will be downloaded, it SHOULD be a location on external storage (DCIMDir). It's working fine now. Since our app is already released and I don't want to change the code, do you have any advice? Thanks for a great library! @RonRadtke

truongnv98 avatar Jul 31 '24 09:07 truongnv98

Thank you.

If you don't see any errors or problems just keep it as it is. Otherwise feel free to change somewhen later. Since I think it is a nice feature I will regardless bring it live. Will ease the usage

RonRadtke avatar Jul 31 '24 18:07 RonRadtke

I have an issue with copying video files now on Android. If I use copyToMediaStore with mimeType: 'video/mp4' and mediatype = 'Video', it saves the file without extension (.mp4) in my case. Even if the file name and path both contain this extension, resulting file doesn't.

If I try to put a config like ReactNativeBlobUtil.config({appendExt: 'mp4'}).MediaCollection.copyToMediaStore(...), it says Cannot read property 'copyToMediaStore' of undefined.

For example, copyToMediaStore result is resolved to string like content://media/external_primary/downloads/1000000041. But the interesting thing, that in fact if I open a gallery, I see this file really saved and it's path is completely different from what copyToMediaStore returned to me and it does contain extension and the path is /storage/emulated/0/Download/

I'm using the latest available version of the library - 0.19.11

wrldh avatar Aug 19 '24 14:08 wrldh