Navigating Network Errors in React Native HTTP/HTTPs API Calls: Addressing Android Device Restrictions



Introduction:

Developing mobile applications with React Native brings about its own set of challenges, particularly when dealing with HTTP APIs. A common hurdle developers face is network errors, especially on Android devices, where requests may be blocked. In this article, we'll dive into the intricacies of handling network errors specific to HTTP APIs in React Native, focusing on Android device restrictions. We'll guide you through the configuration steps necessary to overcome these challenges and ensure seamless API calls.



Configure Network Security in AndroidManifest.xml


In your Android/app/src/main/AndroidManifest.xml file, add the following lines to address Android's network security requirements

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:usesCleartextTraffic="true" <!-- Add this line -->
android:theme="@style/AppTheme">
<!-- ... other configurations ... -->
</application>
</manifest>


With these additions, you enable your app to make HTTP API requests.

If you encounter network errors while working with HTTPS APIs, and the previous solution doesn't resolve the issue, follow these additional steps


Create a CustomClientFactory:
  1. Create a file named "CustomClientFactory.java" in the same folder as your MainActivity.java.
  2. Add the following content to the "CustomClientFactory.java" file:

package <your-package-name-same-as-in-MainActivity.java>;

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

import java.security.cert.CertificateException;
import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.TimeUnit;


import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;

import static android.content.ContentValues.TAG;

public class CustomClientFactory implements OkHttpClientFactory {

@Override
public OkHttpClient createNewNetworkModuleClient() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
.hostnameVerifier((hostname, session) -> true); // Bypass hostname verification

OkHttpClient okHttpClient = builder.build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

Replace <your-package-name-same-as-in-MainActivity.java> with your actual package name (The same as in MainActivity.java).

Integrate CustomClientFactory in MainActivity:

In your MainActivity.java, import the CustomClientFactory and invoke in onCreate

....
....
import com.akhilbhartiyajansang.CustomClientFactory; // Add this

public class MainActivity extends ReactActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this);
OkHttpClientProvider.setOkHttpClientFactory(new CustomClientFactory()); //Add this
super.onCreate(null);
}

....
....
}
}


Now, with these configurations, you should be able to make API calls successfully, addressing both HTTP and HTTPS scenarios.

Conclusion:

By following these step-by-step configurations, you ensure that your React Native app can seamlessly communicate with HTTP and HTTPS APIs on Android devices. These adjustments empower developers to overcome network challenges, delivering a robust and reliable mobile application experience. Thank you for reading, and happy coding!

1 Comments

  1. This very a helpfull for me. Thanks Naveen for making this artical

    ReplyDelete
Previous Post Next Post