Phil Mok
Phil Mok

Reputation: 4050

React Native network request fails on iPhone but succeeds in iOS simulator

As many people have suggested in answers to similar questions, I have edited my info.plist by adding:

<key>NSAllowsArbitraryLoads</key>
<true/>

I have also made sure in Xcode that arbitrary loads are allowed: enter image description here

Everything works perfectly fine in the iOS Simulator but when I try to make a network request on my iPhone I get this error in the remote debugger:

TypeError: Network request failed
    at XMLHttpRequest.xhr.onerror (fetch.js:441)
    at XMLHttpRequest.dispatchEvent (event-target.js:172)
    at XMLHttpRequest.setReadyState (XMLHttpRequest.js:542)
    at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:378)
    at XMLHttpRequest.js:482
    at RCTDeviceEventEmitter.emit (EventEmitter.js:181)
    at MessageQueue.__callFunction (MessageQueue.js:236)
    at MessageQueue.js:108
    at guard (MessageQueue.js:46)
    at MessageQueue.callFunctionReturnFlushedQueue (MessageQueue.js:107)

I've restarted Xcode more times than I can count at this point. I've never had this issue with any other app. Here the code from the request, the error comes from the second catch from the bottom:

loginFinished (error, result) {
  if (error) {
    console.log(error)
    alert("Login failed with error: " + error);
  } else if (result.isCancelled) {
    alert("Login was cancelled");
  } else {
    AccessToken.getCurrentAccessToken()
      .then(response => {
        console.log('1',response)
        fetch(`http://localhost:3000/auth`, {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            fbAccessToken: response.accessToken
          })
        })
        .then(response => response.json())
        .then(data => {
          console.log('data: ', data)
          this.props.setUser(data)
        })
        //Network error comes from this catch
        .catch(err => console.log(err))
      })
      .catch(err => console.log(err))
  }
}

Upvotes: 2

Views: 1191

Answers (1)

ide
ide

Reputation: 20788

The problem is that you are trying to access localhost from your phone. When you run the iOS simulator on the same computer as your server that works fine, but your phone needs the hostname or IP address of your computer. These are a few ways you could solve this:

  • Run a network tunnel like ngrok on your computer (ngrok http 3000) and access it at http://<hash>.ngrok.io. Since ngrok does TLS termination you'll be able to test HTTPS URLs as well.
  • Find the hostname of your computer and access it at http://<hostname>.local:3000. This requires your computer and router to support Bonjour.
  • Find the LAN IP address of your computer and access it at http://<ip>:3000

Upvotes: 3

Related Questions