Axios post request network error on android - ios

So i'm posting a formdata object with axios to a node.js server. On iOS everything works perfectly, the data get posted and the image uploaded. But on android i'm getting this error
[AxiosError: Network Error]
here's my axios call
const handleSubmit = async (listing, { resetForm }) => {
const data = new FormData();
listing.images.forEach((image, index) =>
data.append("images", {
name: `product${Math.floor(Math.random() * 1000)}.`,
uri: image,
})
);
const res = await axios
.post("http://192.168.43.8:5000/products/addProduct", data, {
headers: {
"Content-Type": "multipart/form-data",
},
//tried adding this but didn't work out
transformRequest: (data) => data,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
// handle error
});
}
}
Please note that on iOS it works without a problem.
here's a screenshot of the error when i used the react native debugger

if you use android emulator you need to change your ip to 10.0.2.2
change this:
http://192.168.43.8:5000/products/addProduct
to this:
http://10.0.2.2:5000/products/addProduct

By default http calls are blocked from android 9 version onwards, you either need to make your api calls HTTPS or you need to explicitly allow connection to this IP in your manifest file. Please refer this SO thread. How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?

For me i am getting axios error for my emulator and did not getting any error for ios simulator. The problem with my emulator is that it is not able to connect to Internet.
So I added google DNS server 8.8.8.8 (you can add any DNS server) for my mac and it worked.

Related

How do I get my physical device running React Native on Expo Go to communicate with my app's rails backend api?

I am currently trying to run my react-native/rails app on my phone for testing purposes. I can run my sign in and log in screens fine because they do not communicate with my server until the user info is entered. When running my server i use:
$ rails s --binding=0.0.0.0
I do not receive any errors other than knowing my server is not being communicated with. This all works fine on my Android Studio Emulator as well.
// one of my fetch GET requests
export function requestCurrentUser(username, auth_token) {
return function action(dispatch) {
const request = fetch(`'http://10.0.2.2:3000'/users/${username}`, {
method: 'GET',
headers: {
"Authorization": auth_token
}
});
return request.then(
response => response.json(),
err => console.log("user error"),
)
.then(
json => dispatch(receiveCurrentUser({id: json.id, email: json.email, username: json.username})),
err => console.log("user json error"),
);
}
}
I've tried changing my Phone IP settings to a 10.0.2.2 Gateway, and using my phone's IP in my fetch request. I feel like I am missing something conceptually. Thanks in advance.
In fetch request you need to use the IP from the machine that are running the rails server,
probably your notebook and use the same network to connect your app and your rails backend api. In order to test, you can try directly access your api in your phone browser accessing http://IP_FROM_RAILS_MACHINE:3000

Cross origin error when using cloud functions in back4app

Getting CORS error when calling cloud function in back4app.
Error:
Access to XMLHttpRequest at
'https://parseapi.back4app.com/functions/hello' from origin
'http://localhost:8100' has been blocked by CORS policy: No 'Access-
Control- Allow-Origin' header is present on the requested resource.
In client code cloud function implemented in home page
home.page.ts:
Parse.Cloud.run('hello').then(function (ratings) {
console.log("updated");
}).catch((error) => {
console.log(error);
console.log("fail");
});
Cloud function:
In back4app added main.js file with cloud code implementation
main.js:
Parse.Cloud.define('hello', function(req, res) {
Parse.Cloud.useMasterKey();
return 'Hi';
});
It can be related to the Parse Server version.
Can you please take a look to check what is the Parse Server version that you are using? Please, find this info following this guide.
If it is 2.X, you must deploy a function with the structure below:
main.js:
Parse.Cloud.define('hello', function(req, res) {
response.success('Hello')
});
The code Parse.Cloud.useMasterKey(); is deprecated. Read more here.
If it is the 3.X, you can deploy something like:
Parse.Cloud.define('hello', (req) => {
return 'Hello';
});
Check if you have initialized the correct keys on your frontend side.
If it still doesn't work, please contact the Back4App team in the live chat =D

fetch is redirected to custom url scheme and fails

I have a react native project where i am sending a http request through fetch() to a page that redirects me to a url scheme like appname://data=123456.
I need to extract those data from the location url and then continue with other requests to a api. The problem is that ios has problems with this. Android chomps it righ up and it works without problems, but on ios i get a "Network request failed" result.
After some longer debugging i found out that the implementation behind react native catches a error stating "unsupported URL".
Is there any way to make this work? I was trying something along the lines of starting up an app with custom URL scheme, and now appname:// written into safari starts up my app, but it had no effect for the request.
Code i am using for the request: OAUTH2_IS_URL is https://login.server.com and action /api/login
const postData = {username, password};
return fetch(BuildConfig.OAUTH2_IS_URL + action, {
method: 'POST',
credentials: 'same-origin',
mode: 'same-origin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: Object.keys(postData).map(key => key + "=" +
encodeURIComponent(postData[key])).join('&')
});
What I understood from your question is that you are trying to open up an app with the URL that comes from a fetch request.
If that is the case you should use Linking API of react-native. You can test if the URL is supported with canOpenURL() and then start the app with openURL()
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log('Can\'t handle url: ' + url);
} else {
return Linking.openURL(url);
}
}).catch(err => console.error('An error occurred', err));

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:
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))
}
}
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

React Native Network request Failed on fetch - Works Local

I am using some code in a React Native component that is a simple fetch passing a parameter to OMDB API. This could be a CORS issue since if I run it in the format below going directly to omdbapi.com it fails always with Network request Failed. This request however works in the Android emulator on the same network.
// The fetchData function makes an AJAX call to the OMDB API.
fetchData(movieinput) {
console.log("In fetch");
// We pass the movie the user entered in into the URL for the API call.
fetch('http://www.omdbapi.com/?t='+movieinput+'&y=&plot=short&r=json')
.then((response) => response.json())
.then((responseData) => {
// After the data is recieved, we set this.state.movie to the result of the API call.
this.setState({
movie: responseData,
});
})
.done();
}
If however I run the same code going to a local URL that wraps the remote request into a localhost request, it works correctly.
fetchData(movieinput) {
console.log("In fetch");
// We pass the movie the user entered in into the URL for the API call.
fetch('http://localhost:3000/movie/'+movieinput)
.then((response) => response.json())
.then((responseData) => {
// After the data is recieved, we set this.state.movie to the result of the API call.
this.setState({
movie: JSON.parse(responseData),
});
})
.done();
}
Any ideas?
The problem is probably App Transport Security, an iOS specific restriction that (by default) forces apps to use https for all network communication. Here is a video tutorial explaining how to tweak ATS so that your react native app will work: http://codecookbook.co/post/how-to-make-network-requests-in-react-native/

Resources