Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native & okhttp on Android - Set User-Agent

I'm trying to set the User-Agent with React Native on Android. Did some research and it looks like I should use an okhttp Interceptor. An example that I've found explains how this should be done(Link) but then I am not sure on how to register the Interceptor.

So in order to set the User-Agent I am using this class:

public class CustomInterceptor implements Interceptor {
    @Override public Response intercept(Interceptor.Chain chain) throws IOException {
      Request originalRequest = chain.request();
      Request requestWithUserAgent = originalRequest.newBuilder()
          .removeHeader("User-Agent")
          .header("User-Agent", "Trevor")
          .build();
      return chain.proceed(requestWithUserAgent);
    }
}

Then what's left is to register the above interceptor so where it should be done? Maybe in MainActivity.java?

OkHttpClient okHttp = new OkHttpClient();
okHttp.interceptors().add(new CustomInterceptor());

I am not getting any errors when building the app so I think that the CustomInterceptor should be fine - just need to make the app use it.

UPDATE: I'm currently trying to register the interceptor in MainActivity but it won't pick it up:

public class MainActivity extends ReactActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    OkHttpClient client = new OkHttpClient();
    client.networkInterceptors().add(new CustomInterceptor());

  };

};
like image 846
manosim Avatar asked Jan 31 '16 21:01

manosim


2 Answers

None of the answers here worked for me for RN 0.63.2. I was able to get it working and in my research was able to find the (albeit very scarce) documentation for the support of this feature.

The only documentation I could find for this was this PR where someone added support for this feature (and broke the currently accepted answer). When I tried adding the interceptor as documented in the PR I got an exception related to CookieJar which I was able to find a solution to in this (unresolved 🙄) issue.

TLDR:

Add a Java class in the same folder as your MainApplication called UserAgentInterceptor.java and place this in it:

package YOUR.PACKAGE.NAME; // <-- REPLACE ME

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class UserAgentInterceptor implements Interceptor {

  public UserAgentInterceptor() {}

  @Override
  public Response intercept(Interceptor.Chain chain) throws IOException {
    Request originalRequest = chain.request();
    Request requestWithUserAgent = originalRequest.newBuilder()
      .removeHeader("User-Agent")
      .addHeader("User-Agent", "YOUR USER AGENT") // <-- REPLACE ME
      .build();

    return chain.proceed(requestWithUserAgent);
  }

}

Then create another Java class in the same folder named UserAgentClientFactory.java and place this in it:

package YOUR.PACKAGE.NAME; // <-- REPLACE ME

import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.ReactCookieJarContainer;

import okhttp3.OkHttpClient;

public class UserAgentClientFactory implements OkHttpClientFactory {
  public OkHttpClient createNewNetworkModuleClient() {
    return new OkHttpClient.Builder()
      .cookieJar(new ReactCookieJarContainer())
      .addInterceptor(new UserAgentInterceptor())
      .build();
  }
}

Then in your MainApplication onCreate method register the factory like this:

...
import com.facebook.react.modules.network.OkHttpClientProvider;
...

@Override
public void onCreate() {
  super.onCreate();

  OkHttpClientProvider.setOkHttpClientFactory(new UserAgentClientFactory());

  // Your other code stuffs

}

And that's it!

like image 151
harryisaac Avatar answered Sep 19 '22 13:09

harryisaac


So I've finally figured it out. Here is the solution for overriding the User-Agent of okhttp3 with React Native.

Create a file called CustomInterceptor.java:

package com.trevor;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class CustomInterceptor implements Interceptor {

    public CustomInterceptor() {}

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request requestWithUserAgent = originalRequest.newBuilder()
            .removeHeader("User-Agent")
            .addHeader("User-Agent", "Trevor")
            .build();

        return chain.proceed(requestWithUserAgent);
    }

}

Then in MainActivity.java override the onCreate method:

...
import com.facebook.react.modules.network.OkHttpClientProvider;
...

public class MainActivity extends ReactActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        attachInterceptor();
    }

    private void attachInterceptor() {
        OkHttpClient client = OkHttpClientProvider.getOkHttpClient();
        client.networkInterceptors().add(new CustomInterceptor());
    }
}

Note that I'm importing com.facebook.react.modules.network.OkHttpClientProvider; and overriding that client instead of creating a vanilla OkHttpClient since this is the one that React Native will use.

like image 42
manosim Avatar answered Sep 17 '22 13:09

manosim