react-native: With React-Native, SSE aka EventSource does not receive Events on Android

Please provide all the information requested. Issues that do not follow this format are likely to stall.

Description

I am trying to use rn-eventsource and react-native-event-source and they always get 200 status when sending a request to the server. However! I am able to receive Events on:

  • iOS emulator
  • my iOS device

but not from:

  • Android emulator
  • my Android device

I can get webpages with the browser provided EventSource to work on Chrome on ios and on Android.

It seems like this is an issue with React-Native on Android.

React Native version:

react-native info
info Fetching system and libraries information...
System:
    OS: macOS 10.15.4
    CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
    Memory: 62.51 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 13.3.0 - ~/.nvm/versions/node/v13.3.0/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.13.1 - ~/.nvm/versions/node/v13.3.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6241897
    Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.2 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0
    react-native: ^0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Install rn-eventsource or react-native-event-source
  2. Setup a simple EventSource("https://..../sse_listen")
  3. setup .onmessage, .onopen and .onerror which do console.log
  4. Look at the logs emitted by .onmessage .onopen and .onerror
  5. Notice that logs appear for iOS but not for Android

Expected Results

Events appear on Android

More details: I’m pasting the comments I added to this thread : https://github.com/react-native-community/discussions-and-proposals/issues/99 ::

I'm having trouble getting this to work at all on my Android device and on my Android emulator. The server does receive the GET request, but the client never receives any messages. I'm not sure how to troubleshoot or debug this at all.

It works on ios and ios emulator, it works in Chrome App on ios and Android. I tried using mitmweb but that didn't show the returned Events.

In the Android Studio Network Traffic Monitoring tool, the returned events do not show up.

tail -f /var/log/nginx/error.log doesn't seem to show any issues.

Here are the differences in the headers sent in the request:

Android
{
"x-forwarded-for":"ip",
"host":"mysite.com",
"connection":"close",
"cache-control":"no-store",
"accept":"text/event-stream",
"user-agent":"okhttp/3.14.1"
"accept-encoding":"gzip",
}

iphone:
{
"x-forwarded-for":"ip",
"host":"mysite.com",
"connection":"close",
"cache-control":"no-store"
"accept":"text/event-stream",
"user-agent":"AppName/1 CFNetwork/1121.2.2 Darwin/19.3.0",
"accept-encoding":"gzip, deflate, br",
"accept-language":"en-us",

}

I'm not sure if the issue is with RCTNetworking or with rn-eventsource. My guess is that since this is failing with both rn-eventsource and with simple xhr, that the issue is in RCTNetworking?

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 8
  • Comments: 20

Commits related to this issue

Most upvoted comments

Try to disable Flipper network interceptor. Go to android/app/src/debug/java//ReactNativeFlipper.java and comment next lines of code:

  // try to comment this code
  NetworkingModule.setCustomClientBuilder(
    new NetworkingModule.CustomClientBuilder() {
      @Override
      public void apply(OkHttpClient.Builder builder) {
        builder.addNetworkInterceptor(new     FlipperOkhttpInterceptor(networkFlipperPlugin));
      }
    }
  );

In case you are using expo SDK 50, you could try with the plugins i’ve developed to patch the Android SSE issues while in debug variant (both are needed):

  • react-native: comment out flipper
  • expo: patch ChromeDevTools Interceptor

expo-sse-patch

Edit: note to the react-native team, perhaps the flipper issue is caused by the same type of problem as described there: https://github.com/expo/expo/issues/27526 ?

hey guys, I found these interesting library, to try to solve the android problem with pure js solution:

Try to disable Flipper network interceptor. Go to android/app/src/debug/java//ReactNativeFlipper.java and comment next lines of code:

  // try to comment this code
  NetworkingModule.setCustomClientBuilder(
    new NetworkingModule.CustomClientBuilder() {
      @Override
      public void apply(OkHttpClient.Builder builder) {
        builder.addNetworkInterceptor(new     FlipperOkhttpInterceptor(networkFlipperPlugin));
      }
    }
  );

The flipper network interceptor was in fact responsible for react-native-sse not working on Android. The above did not work for me, but the following did. In this code, I have added a boolean variable shouldAddInterceptor that you can set based on your conditions. If shouldAddInterceptor is true, the interceptor will be added. If false, it won’t be added. You will need to replace shouldAddInterceptor with your condition for whether or not to add the Flipper network interceptor:

` public class ReactNativeFlipper { public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (FlipperUtils.shouldEnableFlipper(context)) { final FlipperClient client = AndroidFlipperClient.getInstance(context);

  client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
  client.addPlugin(new DatabasesFlipperPlugin(context));
  client.addPlugin(new SharedPreferencesFlipperPlugin(context));
  client.addPlugin(CrashReporterPlugin.getInstance());

  NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
  
  boolean shouldAddInterceptor = false; // set this based on your conditions
  
  if (shouldAddInterceptor) {
    NetworkingModule.setCustomClientBuilder(
      new NetworkingModule.CustomClientBuilder() {
        @Override
        public void apply(OkHttpClient.Builder builder) {
          builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
        }
      });
  }

  client.addPlugin(networkFlipperPlugin);
  client.start();

  // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
  // Hence we run if after all native modules have been initialized
  ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
  if (reactContext == null) {
    reactInstanceManager.addReactInstanceEventListener(
        new ReactInstanceEventListener() {
          @Override
          public void onReactContextInitialized(ReactContext reactContext) {
            reactInstanceManager.removeReactInstanceEventListener(this);
            reactContext.runOnNativeModulesQueueThread(
                new Runnable() {
                  @Override
                  public void run() {
                    client.addPlugin(new FrescoFlipperPlugin());
                  }
                });
          }
        });
  } else {
    client.addPlugin(new FrescoFlipperPlugin());
  }
}

} } `

You can just copy/paste this over existing code in the ReactNativeFlipper.java file. Just leave the imports how they are at the top of the file. After this, Android received server sent events as intended with only react-native-sse and react-native-url-polyfill packages. iOS worked fine without any changes.

Do you still have a problem with this?