Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fetch] Does fetch with blob() marshal data across the bridge? #854

Closed
joewood opened this issue Apr 15, 2015 · 21 comments
Closed

[fetch] Does fetch with blob() marshal data across the bridge? #854

joewood opened this issue Apr 15, 2015 · 21 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@joewood
Copy link

joewood commented Apr 15, 2015

When you use .blob() on the response from fetch, is the data actually marshaled across the bridge? Or is the blob a handle on the data on the native side?

@joewood
Copy link
Author

joewood commented Apr 18, 2015

I'm trying to work through the best way of handling a lot of binary data. The best approach is to leave the binary data on the native side. Is the strategy here to use a tag, like how the camera roll refers to? Can fetch be set-up to return a 'blob tag' - equivalent to an 'image tag'?

@brentvatne brentvatne changed the title Does fetch with blob() marshal data across the bridge? [fetch] Does fetch with blob() marshal data across the bridge? May 31, 2015
@ghost
Copy link

ghost commented Aug 4, 2015

Thank you for reporting this issue and appreciate your patience. We've notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.

@nicklockwood
Copy link
Contributor

@joewood this is exactly what I've been considering - storing data on the native side and sending a tag to the JS as the XHR response.

The problem with this approach is controlling the lifecycle of the data. We'd have no way of knowing if JS discarded the tag, so we wouldn't know when to release the data on the native side. We could put it in a LRU cache, but then you have the opposite problem, where the data has been released but you're still holding on to the tag, expecting it to work next time you use it.

I'm open to suggestions.

One option would be to encode enough info in the tag that it can re-download the data again if it's been discarded from the cache. I'm not sure if that would work in practice though.

Another option I've considered is that rather than downloading data to RAM, the "tag" will be a local file URL, and we'll provide a file manager so that the caller can then move or delete that file manually, otherwise it will remain indefinitely.

@nsainaney
Copy link

In my case the blob is an image that I need to get to <Image source={...} />. No suggestions but just reporting a use case.

@ssomnoremac
Copy link

@nicklockwood: curious if there's any progress on this. In my case I need to post the blob after a fetch. Seems like a common use case.

@nicklockwood
Copy link
Contributor

@ssomnoremac we haven't attempted to solve the problem of marshalling arbitrary binary data across the bridge yet, but we support adding file attachments to XHR requests by just specifying the url so that the data never needs to cross the bridge (it will download and upload the data on the native side as a single action).

Alternatively, if it's an image, there's a workaround involving using the ImageStore module to export the image to JS as a base64 string.

@nicklockwood
Copy link
Contributor

@nsainaney I'm a bit unclear on your use case. If you have a url that returns a blob of imageData, can't you pass the url as the <Image> source directly?

@ssomnoremac
Copy link

@nicklockwood: Brilliant, prefer the first option. Second works but increases the payload size. Not sure I follow "specifying the url", I have two urls in my case: a remote and a local (couchbase-lite) device database. is it in fetch docs?

@nicklockwood
Copy link
Contributor

@ssomnoremac I've only tried it with plain XHR, but I assume it works with fetch as well.

The trick is to use our FormData polyfill. It seems like the docs for that aren't on the website, but it's pretty well-documented in the FormData.js file:

https://github.com/facebook/react-native/blob/master/Libraries/Network/FormData.js

@ssomnoremac
Copy link

Great Nick, this looks great. Could be a life saver for our app. Thanks so
much!
On Mar 3, 2016 6:38 PM, "Nick Lockwood" [email protected] wrote:

@ssomnoremac https://github.com/ssomnoremac I've only tried it with
plain XHR, but I assume it works with fetch as well.

The trick is to use our FormData polyfill. It seems like the docs for that
aren't on the website, but it's pretty well-documented in the FormData.js
file:

https://github.com/facebook/react-native/blob/master/Libraries/Network/FormData.js


Reply to this email directly or view it on GitHub
#854 (comment)
.

@nicklockwood
Copy link
Contributor

cc: @mkonicek, @bestander - can we get the FormData docs added to the web site? It's not the first time this has come up, and judging by the number of 3rd party file upload modules, I don't think anyone knows this feature exists.

@mkonicek
Copy link
Contributor

mkonicek commented Mar 4, 2016

@joewood Thanks for flagging this! Would you be up for sending a PR to update the docs?

@experimentsin
Copy link

@nicklockwood One use case we have where it seems passing a URL to <Image> can't help is when the remote image in question is secured and requires a custom access token header to be passed as part of the request. In that case it looks like we need to make a full strength fetch or XHR request to access the data then somehow hand it off locally in such a way that <Image> can address it.

@nicklockwood
Copy link
Contributor

@experimentsin ah, good point. We should extend the image source object to include headers and http method, like the one for webview.

We'd need to do some work on RCTImageLoader as well to make it accept NSURLRequests and not just url strings.

@lu-ko
Copy link

lu-ko commented Mar 11, 2016

@experimentsin +1 It's exactly my case. I'm looking forward for some solution that could be simply used.

@nsainaney
Copy link

@nicklockwood, @experimentsin got it. The image server I'm dealing with requires an auth token in the header.

@bestander
Copy link
Contributor

The problem with this approach is controlling the lifecycle of the data. We'd have no way of knowing if JS discarded the tag, so we wouldn't know when to release the data on the native side. We could put it in a LRU cache, but then you have the opposite problem, where the data has been released but you're still holding on to the tag, expecting it to work next time you use it.

I'm open to suggestions.

@nicklockwood in browsers this problem is solved with URL.createObjectURL().
Developers are supposed to call URL.revokeObjectURL() manually when the binary data in the native memory is no more needed.
It is logical to repeat the same approach in RN.

@wkh237
Copy link

wkh237 commented May 10, 2016

Hi, I also got the problem when upload/download blob data, so I made a RN native module so that I can upload/download blob data then process it in JS context.

Is there any progress on this issue? or there's any way to do this without writing native code?

@lacker
Copy link
Contributor

lacker commented Oct 21, 2016

This issue is asking a question which seems to be answered, so I'm going to close it. I think it's okay if the best answers are libraries like react-native-fetch-blob, for what it's worth - we don't need to solve every single thing inside the core library.

@brentvatne
Copy link
Collaborator

@lacker - revision on that comment: #11103

@austinksmith
Copy link

There seems to be a trend of closing issues that are important for broader implications than simply fetching images and displaying them, data blob creation is important for many use cases and is used widely in many other JvaScript execution environments, please see my latest issue ticket @lacker #16034 (comment)

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests