-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Possible Inefficiency/issues with uploading document provider provided documents #525
Comments
One possible reason the library may be writing to a temporary file first is because the Content-Length needs to be defined, and file size might not be immediately available for custom providers, so the library just doesn't bother with passing around file lengths and just copies the file to the filesystem so it can get a file based input stream. However the way the library does this is wrong in multiple ways for every method you could get a file. To get the Content-Length this library seems to use https://developer.android.com/reference/java/io/InputStream.html#available()
Then after copying the document to the temporary file, for multipart the TL;DR this library is handling files on Android in discouraged and unreliable ways and using inefficient hacks to stop the library from breaking. I'm definitely going to have to overhaul File related portions of this library if it will be at all usable. The proper way to handle files and documents:
|
Just an aside, you may want to also fork and clone https://github.com/wkh237/react-native-fetch-blob-dev Plus my still open PR for that repo: wkh237/react-native-fetch-blob-dev#8 Tests are in The main test file is A patch should pass the relevant tests, or if not, the API change should be documented. If you have trouble setting it up you may find something in the closed issues of that repo, there are one or two minor issues where the documentation is outdated. I had planned to patch the README too but since my PR still is not merged I forgot about it. Overall I found it pretty easy to set this up and run the tests though. If you need help setting it up I'll probably be able to help — unlike with the "fetch" part of RNFB, since I will only touch the filesystem related code. |
We got a crash on production related to this issue. |
I just use my own fork of the 0.10.9 tree. Not a big deal? Anyway, the package owner does not seem to have the time, clearly more help is needed. You can ask him or just maintain your own fork and merge back without time pressure on yourself. That the situation is unsatisfactory is a general problem with ALL open source packages. Github and Co. don't help much with a professionalization — which would require a major effort of monetization, e.g. a subscription fee for all npm packages and maintainers are paid by some agreed-upon key out of that budget. The "it's free!" only goes so far. |
@dantman If this is still relevant, the package has a new maintainer, see the top level README, so there possibly is a chance of getting something done. |
We'd love to see any PR's over at the new repo location! https://github.com/joltup/react-native-fetch-blob |
I've been reviewing the code to see if RNFB is viable for my use case, I've got a document picker on Android (some native code that uses
Intent.ACTION_GET_CONTENT
to let the user select a file and then returns thecontent://
URI provided by the document provider) and I need to upload that document to our API.From what I see in
PathResolver.java
,RNFetchBlobBody.java
, andRNFetchBlobReq.java
it looks like what RNFB does to handle a document provided by a document provider is hacky/inefficient.The
PathResolver. getRealPathFromURI
is called throughnormalizePath
by a bunch of methods that just want to get an InputStream (readFile to read it, various parts of the upload code to upload the data from that stream). To deal with document providers it first skips the standard way of doing things on Android and hardcodes patterns of a few different document providers manipulating the Uris returned by document providers like external stores, file content, google photos, and media provider in order to return something closer to a Filesystem path. If it's not one of them then it usesopenInputStream
andgetCacheDir
to copy the document provided by the document provider to a temporary file (which may involve a network download that doesn't have its progress tracked and blocks the upload; I'm not certain but it almost looks like it might block one of the threads to do this; and may be padding the size of the file to an incorrect length) and it returns the path to that file.The upload code calling that method then uses the path to open an InputStream to that file and uploads from the stream.
So in short:
File
file API. Which I believe may possibly bypass standard permissions granted for something returned by an intent and require extra permissions that aren't actually necessary or possibly not work at all at some point (because it's an entirely non-standard way of getting an InputStream from a document provider Uri). (possibly related to the problem "...exposed beyond app through Intent.getData() " at Android N #358)I think it would be more reasonable to have a different method to
PathResolver.getRealPathFromURI
that instead returns an InputStream directly and doesn't use the path hacks. Methods likereadFile
and the upload body code would call that directly instead of trying to get a path.Then filesystem files would come from the document provider provided stream and if its from a custom or remote document provider that data would stream into the upload as it is being generated or downloaded and be directly reflected in the upload progress provided by RNFS.
The text was updated successfully, but these errors were encountered: