Home » Android » java – React Native & okhttp on Android – Set User-Agent

java – React Native & okhttp on Android – Set User-Agent

Posted by: admin June 15, 2020 Leave a comment

Questions:

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());

  };

};
How to&Answers:

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

Create a file called CustomInterceptor.java:

package com.trevor;

import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.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.

Answer:

React Native is iterating so quickly that the accepted answer didn’t work for me.

For RN 0.27.2 I had to import okhttp3.OkHttpClient in my CustomInterceptor and change the attachInterceptor() method in MainActivity to replace the client.

private void attachInterceptor() {
    OkHttpClient currentClient = OkHttpClientProvider.getOkHttpClient();
    OkHttpClient replacementClient = currentClient.newBuilder().addNetworkInterceptor(new CustomInterceptor()).build();
    OkHttpClientProvider.replaceOkHttpClient(replacementClient);
}

Everything else from ekonstantinidis’s answer works for me.

Answer:

I’ve implemented this functionality using OkHttp and my code is pretty the same as yours – and everything works fine.

Consider using addHeader("User-Agent", "Trevor") instead of header("User-Agent", "Trevor"), because the latter will replace all of already set headers.

I’m using okHttp.networkInterceptors().add(new CustomInterceptor()); instead of okHttp.interceptors().add(new CustomInterceptor());, but I don’t think it’s a matter of concern here.

Update I do it in onCreate() method too. Everything works as it should.

Answer:

Old issue, but we still ran into the same problem with React Native 0.59. This is what we did to fix (in Kotlin), as recent versions of okhttp prevent (and throw an exception) when trying to add an interceptor to an already initialized client:

import android.os.Build
import com.facebook.react.modules.network.OkHttpClientFactory
import com.jaredrummler.android.device.DeviceName
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response

class UserAgentInterceptor(val userAgent: String): Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()

        val correctRequest = originalRequest.newBuilder()
                .removeHeader("User-Agent")
                .addHeader("User-Agent", userAgent)
                .build()
        return chain.proceed(correctRequest)
    }
}

class UserAgentClientFactory(val appName: String, val appVersion: String, val buildNumber: String): OkHttpClientFactory {
    private fun userAgentValue(): String {
        val deviceName = DeviceName.getDeviceName()
        val osVersion = Build.VERSION.RELEASE
        return "$appName/$appVersion (build: $buildNumber; device: $deviceName; OS: Android $osVersion)"
    }

    override fun createNewNetworkModuleClient(): OkHttpClient {
        val builder = com.facebook.react.modules.network.OkHttpClientProvider.createClientBuilder()
        return builder.addInterceptor(UserAgentInterceptor(userAgent = userAgentValue())).build()
    }
}

This was done in a shared library between 2 apps, thus why we passed in the app name, version, and build number.

Usage from the app itself looked like:

private fun configureUserAgent() {
    val versionName = BuildConfig.VERSION_NAME
    val versionCode = BuildConfig.VERSION_CODE
    OkHttpClientProvider.setOkHttpClientFactory(UserAgentClientFactory(appName = "My App", appVersion = versionName, buildNumber = "$versionCode"))
}

This was called from the onCreate method in the main activity of the app.

Hope this helps!