react native Fetch Network request failed on android - android

I'm trying to receive some simple json from mocky.
React native fetch function:
getMemberDomainList = async (name) => {
try {
let response = await fetch('https://5c9cc9ed3be4e30014a7d287.mockapi.io/api/domain', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
let responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
}
I have tested the address in chrome on windows, it returns the expected mock data. But when the function is called on my android phone I get this error
Error from remote debugger
...\node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:2348 TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:4337)
at XMLHttpRequest.dispatchEvent (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10760)
at XMLHttpRequest.setReadyState (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10511)
at XMLHttpRequest.__didCompleteResponse (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10343)
at ...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10449
at RCTDeviceEventEmitter.emit (...\Libraries\Components\DrawerAndroid\DrawerLayoutAndroid.android.js:11)
at MessageQueue.__callFunction (...\Libraries\ART\ReactNativeART.js:362)
at blob:http://localhost:8081/79251787-d190-4650-8040-23d091c08738:2334
at MessageQueue.__guard (...\Libraries\ART\ReactNativeART.js:312)
at MessageQueue.callFunctionReturnFlushedQueue (...\Libraries\ART\ReactNativeART.js:139)
I'm also running a WebView in my app, which is pointing to a web url, it loads perfectly so I am sure that the phone has internet permission and access etc.

In the latest android versions http requests are not allowed by default. Take a look at this post for further information about allowing http request: How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?

Can't get mockapi.io to work. But the error is not persistent when using services such as:
https://jsonplaceholder.typicode.com/todos/1
Might not be an android or react native related problem after all. Also had issues with mockapi.io in postman, though it works fine in chrome.

If you are using emulator then check whether internet is working or not in this emulation using browser. If not check this: Android emulator not able to access the internet
I have also face this problem in emulator but when I generate a release app and install in a real device(andoid 9) then it works fine.

Please check backend response status.
If backend is sending contents using 205 status - 205 RESET CONTENT
Android system recognize it as an error - HTTP 205 had non-zero Content-Length: 25.
You can check the status code on postman.
So, in this case, the error should be fixed on backend.
It should send contents with 200 status code.

Related

TypeError: Network Request Failed when trying to hit local API from android emulator. React-Native

I've seen answers to this question everywhere but none of them seem to work for me.
I'm trying to do a react native fetch from my android emulator and hit my local API running on https://localhost:5002/v1/users.
This is what my fetch looks like right now:
var response: Response = await fetch(`https://10.0.2.2:5002/v1/user/${initialContext.userId}`, {
method: "GET",
headers: {
"Authorization": `Bearer ${initialContext.accessToken}`
}
});
and this is the error that I'm getting:
Possible Unhandled Promise Rejection (id: 0):
TypeError: Network request failed
TypeError: Network request failed
at C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:26139:20
at C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:30727:21
at _callTimer (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:30643:9)
at Object.callTimers (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:30851:9)
at MessageQueue.__callFunction (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:2781:31)
at C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:2513:17
at MessageQueue.__guard (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:2735:13)
at MessageQueue.callFunctionReturnFlushedQueue (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\index.bundle:2512:14)
at C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\debuggerWorker.js:199:58
at process.<anonymous> (C:\Users\raffaele.leo\Downloads\Source-Code\cbt-systems\1.x\trunk\src\CBTravel.Mobile.AirPortal\.vscode\.react\debuggerWorker.js:68:9)
As you can see I've tried running it with 10.0.2.2 (the local host equivalent for the emulator) and I've also tried my computer's IP address. I've also tried running adb reverse and other port forwarding methods.
The hardest part for me to wrap my head around is that if I go to https://10.0.2.2:5002 on chrome on my emulator I'm able to hit my local API. I'm also able to hit an API in the cloud from that fetch statement, just not anything running on local host.
Any ideas would be appreciated.
Actually it's easy to work using ngrok, which acts in between your emulator and localhost(network tunnelling). It provides you with a domain and forwards all your requests to localhost.
You can check this documentation https://ngrok.com/docs

How do I get http content from a https website?

I get "Http failure response for https://www.google.com: 0 Unknown Error" when I request from Secured url.
I am trying to test my ionic/angular mobile app. When I tried with http requests I had problem with Android 9, but with Android 7 was working fine. Anyhow I need to set my backend to public https server. So now I'm testing with https request and none of 7 and 9 Android versions works.
I am using Angular 7 ,
"#ionic/angular": "^4.6.1",
"#ionic-native/core": "^5.0.0",
"rxjs": "~6.5.1"
I made these small functions in order to make my problem simpler.
inside my html file i have this code:
myFile.html
<ion-button
(click)="onStartTest()"
>Click me</ion-button>
<p id="testme"></p>
myFile.page.ts
onStartTest() {
this.taskService.onTest().subscribe(result => {
document.getElementById('testme').innerText = 'result ' + result;
console.log(result);
}, error => {
document.getElementById('testme').innerText = error.message;
console.log('Problem ', error.message);
});
}
myTask.service.ts
onTest() {
return this.http.get('https://www.google.com').pipe(
catchError(err => {
return throwError(err);
})
);
}
At first I tried my server's URL but I changed it to "https://www.google.com" just to verify that the backend is correct.
Also I have an interceptors.ts file that I am using it for authentication, but I am not logged in when I execute the onStartTest() function, but im gonna share it anw.
interceptors.ts
import {Injectable} from '#angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '#angular/common/http';
import {Observable} from 'rxjs';
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('auth_token');
let newHeaders = req.headers;
if (token) {
console.log(token);
newHeaders = newHeaders.set('Authorization', 'Token ' + token);
const modified = req.clone({
headers: newHeaders
});
return next.handle(modified);
} else {
newHeaders = newHeaders.set('Content-Type', 'application/json');
const modified = req.clone({
headers: newHeaders
});
return next.handle(modified);
}
}
}
I think these are the necessary files to share for this problem.
I also tested the url of google with Postman just to be sure that I should get a status 200
I am also aware that there is an "add_header" directive (nginx) that adds 'Allow-access-control-origin' when the response code is 20x or 30x. According to my screenshot with Postman, google is responding with 200 status, but my app still gets status 0 error.
Ignore the first Error. It's a function I use with http when the app begins. Right now im testing https.
I tried superficially to use ionic-native library HTTP but my app totally crashed.
I also execute the command ionic serve --ssl but still nothing.
I read somewhere that for secured connection I need a certificate, but I understood that this is a server's work.
I tried to request from Dark Sky from Vanilla JavaScript and it works fine. So there is something wrong with angular/ionic side and not server's.
What am I missing? I really need to fix this problem soon!
I want to send a secured request to an https url and get the appropriate response.
Your main problem is that you are trying make an API to an unsecure call (http) location (http://192....../mobile/tasks) from a secure origin (https://localhost:8100).
This is clearly indicated in your error message and this is not allowed, and has been answered before
Your second problem is that, for testing purposes, you are trying to call a 3rd party https ressource from your website. This only works if the 3rd party ressource implement CORS, which is not the case for Google and api.darksky.net. Sending a GET request with Postman is useless, as Postman will not check for CORS headers before displaying the response. If you want to use Postman to check CORS, send an OPTIONS request to these ressources and you'll see that there are no CORS headers
So the answer is in MDN - CORS
For security reasons, browsers restrict cross-origin HTTP requests
initiated from scripts. For example, XMLHttpRequest and the Fetch API
follow the same-origin policy. This means that a web application using
those APIs can only request resources from the same origin the
application was loaded from, unless the response from other origins
includes the right CORS headers.
This means the back-end I was using needed some more configuration since I was using 'same-origin' policy script. I thought we had it because when we tried from the browser's console to fetch the request it was working fine, but on mobile it wasn't. We had a custom CORS configuration but we changed it to the django-cors-headers. Since we switched to django-cors-headers I could get correctly the response from HTTP and HTTPs requests.
The other answer and comments were really useful to focus to the right direction.

403 Forbidden on Fetch post request, but only with some Android Browser

I have different results (204 and 403) using fetch from Android default browser.
A router.post(/page) is configured on express
Express is using helmet
A whatwg-fetch post request is sent by the browsers
Two apps are running on the same machine with different domains (stage.domain.com and domain.com), they have same nginx config and .env for node (both have also NODE_ENV=production)
Both environment are using cloudflare
On the stage.domain.com environment I'm ALWAYS getting 204 -> GOOD
On the domain.com environment I'm getting 403 for almost every Android default browsers.
More: with some android browser (SamsungBrowser/9.4) I'm getting 204 -> GOOD but only with beta version and incognito mode.
I did try to set the User-Agent header, but it is overwritten by the mobile browser.
I did also try to change "credentials" parameter to "same-origin", but it breaks other more requests.
Anyway, as I wrote: this is ALWAYS working under stage.domain.com
Here's my request:
fetch(url, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type':'application/json',
'Accept':'application/json',
'Cache': 'no-cache',
'X-CSRF-Token': formData._csrf
},
body: JSON.stringify(formData)
}).then(function (response) {...
I'm getting crazy on this 403. Knowing what changes in samsung browser between standard/incognito/beta may help.
It may be a Chromium issue, but why should it work on stage.domain.com then?
Thank you for any kind of reply :)

React Native - Not getting response of a API(response size is large around 600KB) when application running on mobile

I have a API which is called in my react native application.
This API is a has request method as GET. Also gzip(compression) is enabled on the server on which this API is hosted. The response size of this API around 678 KB and after gzip it is 239 KB.
When my react native application is running in debug mode then I am getting the complete and proper response from the API.
But when the application is installed on the actual device then I am not getting the response and its giving size as 0.
Following is the code for the API call -
async function getAppPropertiesFromApi() {
try {
let response = await fetch(
'https://myserver.com/api/getProperties',{method: "GET"}
);
let responseJson = await response.json();
return responseJson.appProps;
} catch (error) {
console.error(error);
}
}
Is there any limitation on the response size when the application is running on the device ?
Note - I am getting proper response for the other API's that i am calling from my react native application. I am using fetch for the API communication.
Please provide me some pointers in this area and let me know if there is some change that i need to do to get the proper response. Thanks!
I figured out this problem and it's not related to any size constraints.
The mentioned API was expecting a Accept-Language header in the coming request. So when the application was running in debug mode on the rnd, the request were sent through the chrome browser and the browser by default attaches the Accept-Language header in the request. But when it was not running in the debug mode at that no Accept-Language header was sent in the header of the request, hence the issue was coming as I was not getting any data.
For fixing this I have added Accept-Language header in the request that are going through the mobile application.

React Native on Android, ajax call with fetch fails

I am developing an Android app using React Native. I am testing my app on a Galaxy Nexus API 23 that is being emulated in Android Studio, running on a mac.
I wish to allow users to share information with each other. I am running a webserver with php and mysql, and I want the app to make requests to the server to share data between users.
I am trying to make a POST request to my development server using the Fetch API. My js code is below:
var AjaxEngine = {
test: function() {
return fetch('http://10.0.2.2/test.json')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}
};
called by AjaxEngine.test();
In my emulator I receive the following error:
ExceptionsManager.js:70 TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:23711:8)
at XMLHttpRequest.dispatchEvent (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:9740:15)
at XMLHttpRequest.setReadyState (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:25157:6)
at XMLHttpRequest.__didCompleteResponse (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:25015:6)
at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:25090:52
at RCTDeviceEventEmitter.emit (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:8977:23)
at MessageQueue.__callFunction (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:7065:23)
at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:6969:8
at guard (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:6917:1)
at MessageQueue.callFunctionReturnFlushedQueue (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:6968:1)
test.json consists of:
{
"message":"hello world"
}
The request is successful when I replace 'http://10.0.2.2/test.json' with 'http://facebook.github.io/react-native/movies.json', so the function itself is ok.
'http://localhost/test.json' and 'http://127.0.0.1/test.json' both load in a web browser, curl, and wget. I have also tried replacing the 10.0.2.2 with 127.0.0.1. I have also tried using my local ip (129.xxx.x.x)
What do I need to do to make these requests work? How do I access my development server running on localhost from the emulated android app?
If you get curl to work, try the -D option, which writes the headers to a file. That way, you can see if both requests have f.ex. the same mime type.
-D, --dump-header <file>
Write the protocol headers to the specified file.
This option is handy to use when you want to store the headers
that an HTTP site sends to you. Cookies from the headers could
then be read in a second curl invocation by using the -b,
--cookie option! The -c, --cookie-jar option is a better way to
store cookies.

Categories

Resources