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

Comments

Projects
None yet
@joewood

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

This comment has been minimized.

Show comment
Hide comment
@joewood

joewood 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'?

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 from Does fetch with blob() marshal data across the bridge? to [fetch] Does fetch with blob() marshal data across the bridge? May 31, 2015

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost 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.

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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Aug 4, 2015

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.

Contributor

nicklockwood commented Aug 4, 2015

@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

This comment has been minimized.

Show comment
Hide comment
@nsainaney

nsainaney Dec 7, 2015

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

nsainaney commented Dec 7, 2015

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

This comment has been minimized.

Show comment
Hide comment
@ssomnoremac

ssomnoremac Mar 3, 2016

@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.

ssomnoremac commented Mar 3, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Mar 3, 2016

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.

Contributor

nicklockwood commented Mar 3, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Mar 3, 2016

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?

Contributor

nicklockwood commented Mar 3, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@ssomnoremac

ssomnoremac Mar 3, 2016

@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?

ssomnoremac commented Mar 3, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Mar 3, 2016

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

Contributor

nicklockwood commented Mar 3, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@ssomnoremac

ssomnoremac Mar 4, 2016

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" notifications@github.com 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)
.

ssomnoremac commented Mar 4, 2016

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" notifications@github.com 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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Mar 4, 2016

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.

Contributor

nicklockwood commented Mar 4, 2016

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

This comment has been minimized.

Show comment
Hide comment
@mkonicek

mkonicek Mar 4, 2016

Contributor

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

Contributor

mkonicek commented Mar 4, 2016

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

@experimentsin

This comment has been minimized.

Show comment
Hide comment
@experimentsin

experimentsin Mar 4, 2016

@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.

experimentsin commented Mar 4, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Mar 4, 2016

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.

Contributor

nicklockwood commented Mar 4, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@lu-ko

lu-ko Mar 11, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@nsainaney

nsainaney Mar 11, 2016

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

nsainaney commented Mar 11, 2016

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

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Mar 11, 2016

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.

Contributor

bestander commented Mar 11, 2016

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

This comment has been minimized.

Show comment
Hide comment
@wkh237

wkh237 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?

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

This comment has been minimized.

Show comment
Hide comment
@lacker

lacker Oct 21, 2016

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne Dec 2, 2016

Collaborator

@lacker - revision on that comment: #11103

Collaborator

brentvatne commented Dec 2, 2016

@lacker - revision on that comment: #11103

@austinksmith

This comment has been minimized.

Show comment
Hide comment
@austinksmith

austinksmith Oct 3, 2017

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)

austinksmith commented Oct 3, 2017

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.