This is something that happens to me on every React Native project.
How can I make a request to my local API (that runs on localhost)?
To be able to do a request to your local machine you have to do two things.
First, you must use your machine IP as the base URL for the request.
To discover your IP, just type this command on your console and look for the inet that looks like 192.168.1.200.
ifconfig | grep inet
---
**inet** 192.168.1.200 netmask ...
After that you will need to update your Android and iOS configurations.
Android
One of the problems may be related to CLEARTEXT HTTP, which protects apps from accidental usage of cleartext traffic.
Starting with Android 9 (API level 28), cleartext support is disabled by default.
* from Android Developers
Which means that Android can only make a request to HTTPS sources. So we need to allow our application to use HTTP sources.
In the AndroidManifest.xml file, we need to add these lines:
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network\_security\_config"...>
<activity android:name=".MainActivity" ...>
...
</activity>
</application>
</manifest>
This will allow our application to connect to EVERY HTTP source. But we want to allow only your machine’s IP. So to do that we will need to create the network_security_config.xml file in the folder main/res/xml.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false"> localhost </domain>
<domain includeSubdomains="false"> 10.0.2.2 </domain>
<domain includeSubdomains="false"> 192.168.1.200 </domain>
<base-config cleartextTrafficPermitted="true"/>
</domain-config>
</network-security-config>
This file restricts the HTTP domains that our app can communicate with. The IP 10.0.2.2 is an alias for the emulator to 127.0.0.1, and 192.168.1.200 is our machine’s IP.
After that we need to set the domain url on the Android emulator. So open Dev Settings by clicking CMD + M and then click on Debug server host & port for device. On this modal we add our machine’s IP 192.168.1.200.
iOS
On the iOS side we will have the same issue, we need to allow our app to do requests to *HTTP * sources.
By default, iOS will block any request that’s not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with http) you will first need to add an App Transport Security exception. If you know ahead of time what domains you will need access to, it is more secure to add exceptions only for those domains; if the domains are not known until runtime you can disable ATS completely. Note however that from January 2017, Apple's App Store review will require reasonable justification for disabling ATS. See Apple's documentation for more information.
* from React Native
To do that we will need to update our Info.plist file and add the NSAppTransportSecurity key.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
On iOS we don’t need to define our machine’s IP because it translates localhost to that.
After that all we need to do is re-install our app on the emulator and it’s done, with this you can now make requests to your local API.
Note: This should only be used on local development environment, don’t commit this to your production app.
Recommended links
- https://developer.android.com/training/articles/security-config
- https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33
- https://reactnative.dev/docs/network
I’m a software developer from Portugal, currently working at Runtime Revolution as a front-end and mobile developer.
Top comments (0)