facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.05k stars 24.32k forks source link

fetch implementation does not support streams from the spec - needs implementation in React Native core #27741

Open pcowgill opened 4 years ago

pcowgill commented 4 years ago

React Native has not implemented fetch on top of native APIs, and the fetch polyfill built on top of XHR does not support streams where response.body is a getter for a ReadableStream.

React Native version:

0.61.4

Steps To Reproduce

Use fetch and see that response.body is undefined rather than a getter for a ReadableStream according the the fetch spec.

Describe what you expected to happen:

I expected for response.body to be defined.

Related issues

https://github.com/facebook/react-native/issues/9629 https://github.com/facebook/react-native/issues/12912 https://github.com/github/fetch/issues/746#issuecomment-573251497 (cc @MattiasBuelens)

pcowgill commented 4 years ago

React Native also has a Canny board for feature requests I previously was unaware of. If you come across this GitHub issue and care about this feature being prioritized, please feel free to upvote it over there as well. Thanks!

https://react-native.canny.io/feature-requests/p/fetch-streaming-body

pcowgill commented 4 years ago

Let's create a fork of github/fetch under the Facebook org so we can open pull requests against it without worrying about breaking legacy browsers that are using github/fetch.

As discussed here https://github.com/github/fetch/issues/746

cc @hugomrdias @cpojer

pcowgill commented 4 years ago

Can we create that fork of github/fetch under the Facebook org?

It looks like improvements to the current fetch solution are getting lots of upvotes on Canny: https://react-native.canny.io/feature-requests/p/fetch-streaming-body https://react-native.canny.io/feature-requests/p/implement-fetch-using-native-implementations-instead-of-fetch-on-top-of-xhr

cpojer commented 4 years ago

The Facebook GitHub org only contains project managed by Facebook. It'll mean we have to take care of releases and everything. I'm not sure if that's a good idea, you'll probably be able to move faster on a separate org. What about react-native-community? @alloy can get you set up with that.

alloy commented 4 years ago

@pcowgill If you’re interested in spear-heading that effort in the react-native-community org, please contact me at eloy.de.enige@gmail.com to get the process started.

pcowgill commented 4 years ago

@cpojer @alloy Thanks for getting back to me! I think that could work. @hugomrdias Do you think that will serve our needs?

We should still keep this issue open though, because eventually we'll want to have a spec-compliant implementation of fetch at the native level in React Native.

alloy commented 4 years ago

Just created the fork and added you, @pcowgill https://github.com/react-native-community/fetch

pcowgill commented 4 years ago

@alloy Thanks! After something is published from that fork and we've tested the polyfill thoroughly, we'll want to make a PR to use the new npm package here https://github.com/facebook/react-native/blob/507379f6faba37e483610e4c35033e7b8d260eb4/Libraries/Network/fetch.js#L16

If anyone else would like to collaborate on that fork, just comment here!

hugomrdias commented 4 years ago

Just created the fork and added you, @pcowgill react-native-community/fetch

can you please add me too, thanks

pcowgill commented 4 years ago

@hugomrdias You should have an invite in your email inbox now. Thanks!

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

pcowgill commented 4 years ago

This issue still requires the community's attention. Thanks!

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

hoangpham95 commented 4 years ago

@pcowgill Interested in this issue. Looking from the surface, do you think it's beneficial to use a different polyfill for fetch?

stale[bot] commented 3 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

tom-sherman commented 2 years ago

I am really interested in bringing spec-compliant fetch to react native. I think there's renewed interest in the OSS community and JS developers to standardise where possible as seen in adding fetch to node.js core and the work Cloudflare, Vercel, Shopify et al are doing in WinterCG.

A spec compliant fetch also aligns with React Native's goals IMO.

Has there been any discussion in how to bring spec compliant fetch to React Native? The polyfill fork is a good start but I'm not sure the caveats especially around performance and bundle size make it suitable for general adoption.

mauricedoepke commented 1 year ago

It is also woth to mention, that with the current state of react natives fetch implementation the new graphql features @defer and @stream don't work. But that is probabbly more related to this issue: https://github.com/facebook/react-native/issues/12912

taixw2 commented 1 year ago

When generative AI became popular, SSE became the dominant API response when developing AI apps, so it became urgent to satisfy stream, otherwise a lot of AI apps would be lost, and people had to use ionic/flutter/native to realize this feature.

taixw2 commented 1 year ago

On iOS, I can successfully receive a text stream using https://github.com/react-native-community/fetch, and I suggest try this library

sergei-stralenia commented 11 months ago

Made a blog post just about how to implement this using the Community fetch polyfill (streaming works like a charm in RN now!)

https://blog.codergautam.dev/how-to-use-streaming-fetch/

Hey man, the article link you sent doesnt't work. Do you have another one? πŸ™ Solving the same problem you've done

fukemy commented 8 months ago

can someone help me, stream not working with my IOS simulator : https://github.com/react-native-community/fetch/issues/24

aretrace commented 5 months ago

@kelset | @javache | @TheSavior; both @tom-sherman and @taixw2 present compelling arguments for why this issue should be resolved promptly.

chengfengfengwang commented 4 months ago

When generative AI became popular, SSE became the dominant API response when developing AI apps, so it became urgent to satisfy stream, otherwise a lot of AI apps would be lost, and people had to use ionic/flutter/native to realize this feature.

React Native seems don't think AI is important...

anirudhsama commented 4 months ago

@codergautam Have you seen any performance issues with this implementation using polyfills? In our experiments, the non stream response was always much faster than waiting for the full stream to finish.

talentlessguy commented 3 months ago

Is there any current blocker to implementing it in the core? Probably it's easier now that there's a community effort to polyfill readable streams / streaming in fetch

iarickvigasi commented 1 month ago

+1. 4 years to this issue, no native support for ReadableStream

LunatiqueCoder commented 1 month ago

My bad, I recently took down my blog since it was not getting enough traffic (I started it as an experiment) Anyways you can see the usage on one of my Stackoverflow Answers: https://stackoverflow.com/questions/56207968/stream-api-with-fetch-in-a-react-native-app/77089139#77089139

☝️ Inspired by this, I managed to come up with the following solution:

  1. Run yarn add react-native-fetch-api react-native-polyfill-globals web-streams-polyfill
  2. If you use TextDecoder, also run yarn add text-encoding
  3. Copy paste the following code snippet in your index.js
// This file was adapted from: https://github.com/facebook/react-native/issues/27741#issuecomment-2362901032

import { polyfill } from 'react-native-polyfill-globals/src/fetch';
polyfill();

// πŸ‘‡ https://stackoverflow.com/a/77744609/14056591
import { ReadableStream as ReadableStreamPolyfill } from 'web-streams-polyfill/dist/ponyfill';
// @ts-ignore
globalThis.ReadableStream = ReadableStreamPolyfill;

// https://stackoverflow.com/a/78858040/14056591
import 'text-encoding';

// Needed for TypeScript:
declare global {
  interface RequestInit {
    /**
     * @description Polyfilled to enable text ReadableStream for React Native:
     * @link https://github.com/facebook/react-native/issues/27741#issuecomment-2362901032
     */
    reactNative?: {
      textStreaming: boolean;
    };
  }
}
  1. Use readable stream:
fetch('https://jsonplaceholder.typicode.com/todos/1', { 
   // https://github.com/facebook/react-native/issues/27741#issuecomment-2362901032
   reactNative: { textStreaming: true } 
}).then(response => { 
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
       .... 
   })
aretrace commented 1 month ago

Full Solution for React Native Text Streaming

πŸ‘‰ https://gist.github.com/aretrace/bcb0777c2cfd2b0b1d9dcfb805fe2838