Alek Hurst
Alek Hurst

Reputation: 4863

React Native fetch() Network Request Failed

When I create a brand new project using react-native init (RN version 0.29.1) and put a fetch in the render method to the public facebook demo movie API, it throws a Network Request Failed. There is a very useless stack trace and I can't debug network requests in the chrome console. Here is the fetch I'm sending:

fetch('http://facebook.github.io/react-native/movies.json')
      .then((response) => response.json())
      .then((responseJson) => {
        return responseJson.movies;
      })
      .catch((error) => {
        console.error(error);
      });

Upvotes: 241

Views: 488281

Answers (30)

Sergey Nasonov
Sergey Nasonov

Reputation: 153

Also make sure your API is actually running

Upvotes: -2

Saptarshi Dey
Saptarshi Dey

Reputation: 205

In my case i just change https to http and the problem was resolved (Using android studio).

Upvotes: 1

Lucas Basquerotto
Lucas Basquerotto

Reputation: 8143

I'm using Expo. I was able to run my app without issues with EAS with the development profile, that has developmentClient: true, while my preview profile that is the same as the development, except without developmentClient defined, gave errors.

Using the following setting (app.config.js) solved the issue:

"plugins": [
  [
    "expo-build-properties",
    {
      "android": {
        "usesCleartextTraffic": true
      }
    }
  ]
]

The setting usesCleartextTraffic allows requests over HTTP (non secure).

I guess it defaults to true when developmentClient: true, but I expected that such a behaviour was documented in the docs (https://docs.expo.dev/build/eas-json/), because it took me some time to solve the issue, and the error itself (Network Request Failed) was not very helpful.

Upvotes: 0

Sir hennihau
Sir hennihau

Reputation: 1814

2023 version

For expo workflow on native platforms, use Constants.expoConfig?.hostUri

If you have a port that you need to use, you can use this snippet:

import Constants from "expo-constants";

const YOUR_API_PORT = "1234"

export const developmentUri = `http://${Constants.expoConfig?.hostUri
    ?.split(`:`)
    ?.shift()
    ?.concat(YOUR_API_PORT)}`;

For react native with web, you can directly use your http://localhost:1234

Upvotes: 0

varun_k_21
varun_k_21

Reputation: 43

I faced same issue now resolved :). I Am using django as backend and react native in expo. Run your Django project on your ipv4 address with python manage.py runserver ipv4address:8080 (you can find your ipv4 address by running ipconfig command in terminal).In react native fetch method use this address. fetch methord=

fetch('http://<your ipv4>:8080/endpoint/', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)})

Upvotes: 1

peterZhang
peterZhang

Reputation: 31

I also have problem is on the android. my android sdk is 28.

I have try and plan. That all unavailable. And my request url is inclues https. request type is post.

after , i founded add the form-data header , can resolve this problem

'Content-Type': 'application/x-www-form-urlencoded'

and the body like this

a=a&b=b

Upvotes: 1

Turjoy Saha
Turjoy Saha

Reputation: 105

Check if your SSL is properly configured putting the url here.

Upvotes: 0

Had the same issue with React-native Expo and Node Express back-end. The problem is about a conflict between an emulator localhost and server localhost. Your back-end-server might be ruunning on 127.0.0.1:8000, but an emulator can't find this.

In terminal find your Ipv4-Address with a command 'ipconfig'. For ex., it will be 192.138.1.40

After this put it into your fetch ( 'http://192.138.1.40:8080/'). And what is also important - run your back-end-server with the same host and port. On Node Express for example:

app.listen(8080, () => console.log("Server is running!"))

Upvotes: 1

amirhosein vakilpoor
amirhosein vakilpoor

Reputation: 26

To find the root problem i used XMLHttpRequest instead of fetch and after sending a request an exception threw with the message that tells the actual problem HTTP_1_1_REQUIRED.

apparently react native (in my case v0.59) fetch only supports http/1.1 then i disabled http/2 on the webserver.

if your webserver is IIS look at this question answer

hope this will help.

Upvotes: 0

Hasan Basri
Hasan Basri

Reputation: 868

If you are connecting to a HTTPS website please check the internet connection of your emulator. (In my case, I'm using a connected phone emulator via USB and it's internet was offline)

Upvotes: 0

Li Zheng
Li Zheng

Reputation: 731

fixed TypeError: Network request failed when upload file to http not https with Android debug builds

In react-native 0.63.2 (I'm testing) or some higher version, if just use fetch to upload file to a http (not https) server, will meet TypeError: Network request failed.

Here I use axios@0.27.2 as client running on an Android phone successfully upload a file to react-native-file-server as server running on another Android phone.

client need edit JAVA and JS code, server no need edit JAVA code.

With debug builds, must commenting out line number 43 in this file android/app/src/debug/java/com/YOUR_PACKAGE_NAME/ReactNativeFlipper.java

38      NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
39      NetworkingModule.setCustomClientBuilder(
40          new NetworkingModule.CustomClientBuilder() {
41            @Override
42            public void apply(OkHttpClient.Builder builder) {
43      //        builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
44            }
45          });
46      client.addPlugin(networkFlipperPlugin);

Maybe also need add android:usesCleartextTraffic="true" under <application of android/app/src/main/AndroidManifest.xml , on my test, it's not necessary on both debug and release builds.

  onFileSelected = async (file) => {
    // API ref to the server side BE code `addWebServerFilter("/api/uploadtodir", new WebServerFilter()`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L356
    // could not be 'localhost' but IP address
    const serverUploadApi = 'http://192.168.1.123:8080/api/uploadtodir';

    // the folder on server where file will be uploaded to, could be e.g. '/storage/emulated/0/Download'
    const serverFolder = '/storage/emulated/0/FileServerUpload';

    const fileToUpload = {
      // if want to upload and rename, it can be `name: 'foo.bar'`, but can not be 'foo'
      // only if your server upload code support file name without type, on our server
      // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L372
      // will cause java.lang.StringIndexOutOfBoundsException in substring()
      name: file.name,

      // type is necessary in Android, it can be 'image/jpeg' or 'foo/bar', but can not be
      // 'foo', 'foo/', '/foo' or undefined, otherwise will cause `[AxiosError: Network Error]`
      type: 'a/b',

      uri: Platform.OS === 'android' ? file.uri : file.uri.replace('file://', ''),
    };

    const form = new FormData();
    form.append('path', serverFolder);
    form.append('uploadfile', fileToUpload);

    // ref to the server side FE code `this.axios.post("/api/uploadtodir", parms, config)`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/fileserverwebdoc/src/views/Manage.vue#L411
    let res = await axios.post(serverUploadApi, form, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress: function (progressEvent) {
        console.warn(progressEvent);
      },
    });

    // ref to the server side BE code `return newFixedLengthResponse("Suss");`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L380
    if (res.data === 'Suss') {
      console.warn('Upload Successful');
    } else if (res.data === 'fail') {
      console.warn('Upload Failed');
    }
  };

Upvotes: 0

cmcodes
cmcodes

Reputation: 1876

It my case, it was showing same for https requests as well.

Reinstalling the application solved it.

Upvotes: 1

lakjeewa Wijebandara
lakjeewa Wijebandara

Reputation: 572

Just add

<uses-permission android:name="android.permission.INTERNET" />

    <application
      android:usesCleartextTraffic="true"

in your AndroidManifest.xml and then replace fetch URL domain (localhost) with your IP address,

const dataRaw = await fetch('http://192.168.8.102:4000');

Upvotes: 3

abhiSHH
abhiSHH

Reputation: 449

"dependencies": {"react": "17.0.2","react-native": "0.66.1"}, I faced this problem with the Android emulator.

  1. Add these lines of code inside AndroidManifest.xml

     <application
      ....
      ....
     android:usesCleartextTraffic="true">
    
  2. Then, try to run your code in a real physical device, instead of emulator,
    to run on physical devices - connect your usb and try to run npx react-native run-android

Upvotes: 0

Mher
Mher

Reputation: 1263

HTTP is not allowed anymore. Pleas use HTTPS

Starting with Android API 28 and iOS 9, these platforms disable insecure HTTP connections by default.

Upvotes: 1

Hend El-Sahli
Hend El-Sahli

Reputation: 6752

For me ... I have https already ... and the issue went away once I added 'Content-type': 'application/json' to headers

headers: {
  Authorization: token,
  'Content-type': 'application/json',
  /** rest of headers... */
}

Platform: Android

Upvotes: 2

Yazan Najjar
Yazan Najjar

Reputation: 2206

if you using localhost just change it :

from :http://localhost:3030 to :http://10.0.2.2:3030

Upvotes: 20

ayoub laaziz
ayoub laaziz

Reputation: 1286

in my case i have https url but fetch return Network Request Failed error so i just stringify the body and it s working fun

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue'
  })
});

Upvotes: 4

aviggiano
aviggiano

Reputation: 1953

In my case, the Android emulator wasn't connected to the Wi-Fi.

See here Android Studio - Android Emulator Wifi Connected with No Internet

Upvotes: -1

Nelson Javier Avila
Nelson Javier Avila

Reputation: 602

The solution is simple update nodejs version 14 or higher

Upvotes: 0

Dharmik
Dharmik

Reputation: 2345

This is not an answer but option. I switched to https://github.com/joltup/rn-fetch-blob It works good both for form-data and files

Upvotes: 1

Rahil Sarvaiya
Rahil Sarvaiya

Reputation: 51

By running the mock-server on 0.0.0.0
Note: This works on Expo when you are running another server using json-server.


Another approach is to run the mock server on 0.0.0.0 instead of localhost or 127.0.0.1.

This makes the mock server accessible on the LAN and because Expo requires the development machine and the mobile running the Expo app to be on the same network the mock server becomes accessible too.

This can be achieved with the following command when using json-server

json-server --host 0.0.0.0 --port 8000 ./db.json --watch

Visit this link for more information.

Upvotes: 3

devkrkanhaiya
devkrkanhaiya

Reputation: 97

  1. Add android:usesCleartextTraffic="true" line in AndroidManifest.xml.

  2. Delete all debug folder from your android folder.

Upvotes: -2

xyz
xyz

Reputation: 100

For android, add android:networkSecurityConfig="@xml/network_security_config" to application tag in AndroidManifest.xml, like this:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ... >
        <application android:networkSecurityConfig="@xml/network_security_config"
                        ... >
            ...
        </application>
    </manifest>

network_security_config.xml file content:

<?xml version='1.0' encoding='utf-8'?>
<network-security-config>
<debug-overrides>
    <trust-anchors>
        <!-- Trust user added CAs while debuggable only -->
        <certificates src="user" />
    </trust-anchors>
</debug-overrides>

<!-- let application to use http request -->
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

Upvotes: -1

kautikmistry
kautikmistry

Reputation: 746

I got the same issue on Android 9 because of the "http" and issue resolved by just adding android:usesCleartextTraffic="true" in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
  android:usesCleartextTraffic="true"
 .......>
 .......
</application>

Upvotes: 45

user3374790
user3374790

Reputation: 257

You should handle the error case in .then for fetch API.

For example:

fetch(authURl,{ method: 'GET'})
.then((response) => {      
  const statusCode = response.status;
  console.warn('status Code',statusCode);
  if(statusCode==200){
    //success code
  }else{
    //handle other error code
  }      
},(err) => {
  console.warn('error',err)
})
.catch((error) => {
  console.error(error);
  return error;
});

Upvotes: 2

henryoats
henryoats

Reputation: 199

I came across the same issue on Android Emulator, where I tried to access an external HTTPS URL with a valid certificate. But fetching that URL in react-native failed

'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }

1) To find out the exact error in the logs, I first enabled 'Debug JS Remotely' using Cmd + M on the app

2) The error reported was

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

3) I added the URL's valid certificate using this method -> STEP 2

http://lpains.net/articles/2018/install-root-ca-in-android/

This certificate gets added to the User tab.

4) Add the attribute android:networkSecurityConfig attribute to AndroidManifest.xml

Add a Network Security Configuration file res/xml/network_security_config.xml:

<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="user"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>

This should work and give you an expected response.

Upvotes: 6

Johannes Spohr
Johannes Spohr

Reputation: 201

I got the same issue on Android but I managed to find a solution for it. Android is blocking cleartext traffic (non-https-requests) since API Level 28 by default. However, react-native adds a network-security-config to the debug version (android/app/src/debug/res/xml/react_native_config.xml) which defines some domains (localhost, and the host IPs for AVD / Genymotion), which can be used without SSL in dev mode. You can add your domain there to allow http requests.

<?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">10.0.3.2</domain>
    <domain includeSubdomains="true">dev.local</domain>
  </domain-config>
</network-security-config>

Upvotes: 17

Craciun Ciprian
Craciun Ciprian

Reputation: 107

if you use docker for the REST api, a working case for me was to replace hostname: http://demo.test/api with the machine ip address: http://x.x.x.x/api . You can get the IP from checking what ipv4 you have on your wireless network. You should have also the wifi from phone on.

Upvotes: 3

ocean
ocean

Reputation: 344

React Native Docs gives the answer for this.

Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's Info.plist (or equivalent) file.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

React Native Docs -> Integration With Existing Apps -> Test your integration -> Add App Transport Security exception

Upvotes: 12

Related Questions