react-native-fetch-blob
react-native-fetch-blob copied to clipboard
Read file from Camera roll (content:// path on android)
I am trying to get the base64 code for an image in the camera roll. The path for the image is something like
content://com.app.provider/app_images/Android/data/com.app/files/Pictures/image-a00a13f4-a24f-40ce-bb16-e56979b75692.jpg
And I am trying to read this file with
RNFetchBlob.fs.readFile(localPath, 'utf8')
and
RNFetchBlob.fs.readFile(localPath, 'base64')
The app simply crashes and in the logcat I can find the error
Column '_data' does not exist
I have also tried
RNFetchBlob.fs.readFile(RNFetchBlob.wrap(localPath), 'base64')
Which gives the error:
Error: Attempt to invoke virtual method 'boolean java.lang.String.startsWith(java.lang.String)' on a null object reference
In the FileSystem API you write that it is possible to read the files from content://
, so I'd like to know if there is another way that I'm not seeing.
EDIT: I'm using RN 0.41 and RNFB 0.10.2
I'm seeing the same thing for readFile
calls to paths within DocumentDir
.
Error: Attempt to invoke virtual method 'boolean java.lang.String.startsWith(java.lang.String)' on a null object reference
at createErrorFromErrorData (NativeModules.js:116)
at NativeModules.js:79
at MessageQueue.__invokeCallback (MessageQueue.js:288)
at MessageQueue.js:127
at guard (MessageQueue.js:46)
at MessageQueue.invokeCallbackAndReturnFlushedQueue (MessageQueue.js:126)
at debuggerWorker.js:71
Android, RN 0.42.
I just found this today. So that's a +1 from me.
Specifically, it's when sharing from Google Drive which give's a URI looking like...
content://com.google.android.apps.docs.storage.legacy/enc%3D2cnEPvlNW2uZUjq8h_w7hhNWmkRhsPqHum9gJTxeOrsaGiV3%0A
Same error pops up, and get's caught in the promise.
Error processing message Error: Attempt to invoke virtual method 'boolean java.lang.String.startsWith(java.lang.String)' on a null object reference
Should mention I'm using the readFile(uri, 'base64') version. Also: RN: 0.35.0 RNFetchBlob: 0.10.0
Thanks for providing the information, will look into this issue ASAP 👍
After some investigation, the problem is that our Android URI resolver couldn't get the absolute file path from the given URI. I will try to figure out if there's a better implementation.
I'm experiencing this in Android 7.1 if that makes any difference. Lmk if you'd like me to test anything.
@ChrisPikul510 @tlvince , is there any way to make a content provider URI like content://com.app.provider/app_images/Android/data/com.app/files/Pictures/image-a00a13f4-a24f-40ce-bb16-e56979b75692.jpg
and content://com.google.android.apps.docs.storage.legacy/enc%3D2cnEPvlNW2uZUjq8h_w7hhNWmkRhsPqHum9gJTxeOrsaGiV3%0A
?
In my case, the URIs from camera roll look like this content://media/external/images/media/694
, and there's no problem to resolve this kind of URI.
Apologies. In my case I'd missed adding a content type prefix altogether; adding file://
to e.g. file://${RNFetchBlob.fs.dirs.DocumentDir}/${filename}
works for me.
@wkh237 I was using https://github.com/marcshilling/react-native-image-picker to take a picture. It saves to the gallery of the phone or selects from the gallery. I can understand if you feel like 3rd party support is not on the top of your list though.
I solved it by storing the base64 directly from the callback instead of getting it from the filesystem.
@nordved , thanks for the information. It'd be great to make this kind of URI supported since it's very common use case IMO 👍
@wkh237 The uri I was attempting came directly from Google Drive app through a share intent. In which case from my end I'm not entirely sure exists as that looks like a hash/temp URI. Are you suggesting I modify the URI?
BTW, is there a way you can implement a function for grabbing N bytes from a file? I ask because I'm only reading this file to grab the first 16 bytes to cross-reference with my list. Which also if you want to integrate here would be cool too. It's just header signature negotiation... https://github.com/ChrisPikul510/content-type-negotiation
@ChrisPikul510 , thanks for the information, though the function is not supported yet but it's on our roadmap (see #124).
However, as a workaround, you can use an undocumented API fs.slice
this API will not be removed as it's used by Blob.slice
polyfill.
fs.slice(src:string, dest:string, start:number, end:number):Promise
which will create a file at path dest
you can then read its content via fs.readFile
.
@wkh237 So if I have this right, a way for me to get the header is to do something like....
RNFetchBlob.fs.slice('file://some/file', CACHE_DIR_FILE, 0, 16)
.then(() => RNFetchBlob.fs.readFile(CACHE_DIR_FILE, 'base64'))
.then((data) => {
//Do something with data
})
.catch(console.warn)
And that should give me only the first 16 bytes correct? But if I have a temp file, then I'll need to unlink it, which seems a bit too complicated computationally for something so simple.
Anyways, any word on the content://
URI's causing this crash?
About the content:// URI's problem, after some investigations I got some clues. In short, we have to handle this kind of URI in a different way, will update the status once it's complete.
I've added additional URI handling to fs.readFile
and fs.readStream
, please try to install the package from branch `issue-287.'
$ npm install --save git://github.com/wkh237/react-native-fetch-blob.git#issue-287
@tlvince I am having the same issue, with the same image picker. How did you do it in the end? Is this the line you updated? fs.readFile(uri, 'base64')
Thanks
@wkh237 Just tried it, it doesn't seem to fix my issue. Below is the URI I am using in fs.readFile
: content://com.app.provider/app_images/Android/data/com.app/files/Pictures/image-2cf9181c-ab81-4fca-8241-fad4ed060156.jpg
. Any ideas?
@etiennewaldron , thanks for the feedback. Will look into the issue and find another possible solution.
Hi, do you have any news on this issue? Is there a quick fix I can use in the meantime? Thanks
@etiennewaldron , I've just updated branch issue-287
, I can read a picture from react-native-image-picker
which has URI like this
content://com.rnfetchblobtest.provider/app_images/Pictures/image-c6f94579-a189-44da-9060-3fc9c613f354.jpg
Please try if that works, thanks 👍
Thank you for the quick response. Tested on Nexus 5X @ 6.0.0 and it's working great! No more app crash for me, everything is working as expected. Thanks again!
I see a similar error when using File System Access API exists(path:string):Promise.
For example:
RNFetchBlob.fs.exists('content://media/external/file/7853') // this is an existing file so this results in true
RNFetchBlob.fs.exists('test') // this is an nonexistent path/file so this results in false
RNFetchBlob.fs.exists('file://...') // true or false
RNFetchBlob.fs.exists('content://media/external/file/7853xxxx') // this is an nonexistent file in an existing folder, but i get an app crash with "Exception in native call java.lang.NullPointerException at java.io.File.<init>(File.java:262)" on top of my stack
Could this be related?
@skr1t , thanks for the reminder, will look into it 👍
I'm wondering if this is still closed though? If fs.exists doesn't think it's threre, then why would the 3rd party app supply the uri? As in the content://com.app.provider
links that I was getting from Google Drive.
Will this be merged/released soon? Thanks!
@wkh237 @jamieparkinson sorry to resurrect this issue, but I am experiencing it myself despite pulling in the issue-287 branch, so I can't see how this is fixed unless I'm missing something. My issue is almost identical to @nordved's original report. Again, I am using ImagePicker as he was. The only slight difference is in the code I am working on, an image is being uploaded as follows:
const result = RNFetchBlob.fetch( 'PUT', url, headers, RNFetchBlob.wrap(uriFromImagePicker))
This throws the following warnings:
RNFetchBlob failed to create single content request body :column '_data' does not exist
and
ReactNativeJS: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference
This is the dependency in my package.json https://github.com/wkh237/react-native-fetch-blob#issue-287
. Am I missing something obvious? I should add that this was working previously but I'm afraid I'm not sure exactly what the breaking change was. I guessing possibly the uri structure returned by ImagePicker.
Many thanks,
Miles
I'm seeing the same problem when copying content uri produced by react-native-image-picker. This line
RNFetchBlob.fs.cp(origin, destination)
Where origin looks like this: content://com.app.provider/app_images/Android/data/com.app/files/Pictures/image-5c38441e-04c7-4497-a28a-24eebb4ac051.jpg
Throws the following error:
Error: Attempt to invoke virtual method 'boolean java.lang.String.startsWith(java.lang.String)' on a null object reference
I'm using the issue-287 branch as dependency (git://github.com/wkh237/react-native-fetch-blob.git#issue-287).
Also having this problem, but the issue-287 branch seems to be working well for me. It's currently 63 commits behind master though. Wondering if you plan on merging this into master? If not, can you bring the branch up-to-date?
@kshvmdn , thanks for the heads up. I fact I was thought the PR #374 is doing the same thing and it has been merged in 0.10.6
have you tried it yet ? If that does not fix the problem, perhaps we will need to merge this one as well.
not working on 0.10.6, and issue-287 gives me stat error: failed to list path
" + path + " for it is not exist or it is not a folder
path == content://com.app.provider/app_images/Android/data/com.app/files/Pictures/image-7402dd55-4003-4094-a53c-69c852d27876.jpg
Just updated branch issue-287
, it's working on my end now. Please update your package from the branch, thanks 👍