alpha0010 / react-native-file-access

Filesystem access for React Native
MIT License
307 stars 19 forks source link

Reading blob data #8

Closed Marvedog closed 3 years ago

Marvedog commented 3 years ago

Bug report

Great work on this library. I am trying to download a pdf from a remote server and store it to external storage on the device. The gist of what I am trying to do is this

Attempt 1: Read file

import {FileSystem} from 'react-native-file-access';

async function getPdf(url: string, options: Object) {
  const res = await fetch(url, options);
  const data = await res.blob();
  const blobPath = URL.createObjectURL(data);
  const data = await FileSystem.readFile(blobPath);  // <--- Error occurs here
  await FileSystem.writeFile('storage/emulated/0/', data);
}

It seems that the readFile function can't find the path of the blob. I have attempted doing the same operation with react-native-fs, and I manage to read blobs there and write them successfully to external storage when they are <~60kB. The error caugth looks like this

[Error: content:/com.app.package.blobs/0db867f8-689d-4e9b-ac73-10185eb9a56d?offset=0&size=51866 (No such file or directory)]

Attempt 2: Copy file

I have also attempted the following

import {FileSystem} from 'react-native-file-access';

async function getPdf(url: string, options: Object) {
  const res = await fetch(url, options);
  const data = await res.blob();
  const blobPath = URL.createObjectURL(data);
  await FileSystem.cpExternal(blobPath, 'name.pdf', 'downloads');
}

Same error :-1:

Env

alpha0010 commented 3 years ago

Have you tried downloading directly to disk (so data does not pass through js)? Something like:

import {Dirs, FileSystem} from 'react-native-file-access';

async function getPdf(url: string, options: Object) {
  const cachePath = Dirs.CacheDir + '/name.pdf';
  await FileSystem.fetch(url, { ...options, path: cachePath });
  await FileSystem.cpExternal(cachePath, 'name.pdf', 'downloads');

  // Optional cleanup:
  await FileSystem.unlink(cachePath);
}
Marvedog commented 3 years ago

Jupp, resolves the issue! Thanks for quick response :+1:

FYI, I think I found the root cause of with reading the blob using

const blobPath = URL.createObjectURL(data);
const data = await FileSystem.readFile(blobPath);  // <--- Error occurs here

It seems that the File implementation from java.io.File only accepts file://[....] URIs. https://docs.oracle.com/javase/7/docs/api/java/io/File.html I am neither a Kotlin or a Java developer so I may be wrong :P