React native how to send requests to localhost? - react-native

first time using React Native with Expo. I saw some tutorials on how to fetch something from locahost but nothing seems to work.
I'm making this simple get request in my backend
app.get("/", async (req, res) => {
res.send("Success");
});
app.listen(5000, () => console.log("Running on 5000"));
On the front end i have
const requestTest = async () => {
try {
const msg = await axios.get("http://192.168.0.29:5000/");
console.log(msg);
} catch (error) {
console.log(error);
}
};
What i tried so far:
Replaced http://localhost:5000/ for my ipv4 address 192.168.0.29, like http://192.168.0.29:5000/.
Since i'm using expo when i start the server it says Metro waiting on exp://192.168.0.29:19000
So i tried to fetch http://192.168.0.29:19000/, also didn't work. After starting the server, i ran this command line adb reverse tcp:5000 tcp:5000, also didn't work.
OBS:
When i connect my app on Expo GO, i'm connecting it through Tunnel, cause if i try to connect it via lan it throws a Network Error.

Related

How to make a fetch request to localhost in React Native/Expo?

I'm creating a React Native/Expo app that uses Deno on the backend. I've created an API in the backend that I can run locally on localhost:4000. When I try to use fetch to call the API in the Expo app, however, I keep getting an error
[Unhandled promise rejection: TypeError: Network request failed] at node_modules/whatwg-fetch/dist/fetch.umd.js:535:17 in setTimeout$argument_0
Here is how I set up the backend
import { Application } from "https://deno.land/x/oak/mod.ts";
import { oakCors } from "https://deno.land/x/cors/mod.ts";
import { APP_HOST, APP_PORT } from "./config.ts";
import router from "./routes.ts";
import _404 from "./controllers/404.ts";
import errorHandler from "./controllers/errorHandler.ts";
const app = new Application();
app.use(oakCors());
app.use(errorHandler);
app.use(router.routes());
app.use(router.allowedMethods());
app.use(_404);
console.log(`Listening on port:${APP_PORT}...`);
And how I use fetch to call the API
const App = () => {
const getData = async () => {
const response = await fetch("http://localhost:4000/something");
const data = await response.json();
console.log(data);
};
useEffect(() => {
getData();
}, []);
return (
...
);
};
Note
Some answers on StackOverflow suggest fetching http://[IP_ADDRESS]:4000/something instead of localhost. I've tried that with no luck.
I've verified that the API is working. I can call it successfully in VSCode's Thunder Client and I can also see the data by going to http://localhost:4000 in the browser.
I found a solution to this issue. I'm running my Expo app on a physical device while my server is running on my computer, on localhost. It makes sense that I'm unable to make requests to localhost on my device, because localhost is not running there.
I fixed this issue by using ngrok, a tool that forwards localhost to a cloud URL, and fetching that URL in the app.
Use the local IP assign to your device, like: http://192.168.20.109:port/api/x
find the local IP using the command "ipconfig" in windows or ifconfig in linux

HTTP requests does not work on my real android device (React Native Expo Tunnel)

I'm facing this issue while posting data to my server via axios.post(). It always catches the error "Network Error" when I run my app on my real android device. But when I use an android emulator device, it works correctly and returns the response. I tried to use "ngrok http 5000" and used the uri that ngrok gave me but that didn't work either. I'm hopeless at this point because my app is using QR code scanner and indie notifications. I'm unable to test it while using emulator. Please help me!
I'm leaving my axios.post() method below
const login = async (email, password, navigation) => {
userState.loading = true;
axios
.post(`http://${localIP}:5000/api/user/login`, {
email,
password,
})
.then((response) => {
userState.loading = false;
userState.user = response.data;
console.log("Data: ", response.data);
navigation.reset({
index: 0,
routes: [{ name: "Home" }],
});
})
.catch((err) => {
userState.loading = false;
console.log("ERR :", err.message);
});
};
I tried to use "ngrok http 5000" and used the uri that ngrok given me but that didn't work either.
Might be a little light on information in order to give a definite answer, it's worth looking at installing a debugger and inspecting the network requests to see where they're going wrong. But here's a couple things to try:
In your AndroidManifest.xml file add the line: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Use http://my.local.ip:port instead of http://localhost:5000 (looks like you're doing this anyway, if not you get this via ipconfig in Command Prompt)
Try adding "Content-Type": "application/json", Accept: "application/json" headers to your Axios request

React Native not allowing public route call to local strapi server

fairly new with strapi and react native. I created a strapi server and created a route that is public, with public authorization to find and find one(Which i'm guessing is the necessary ones to be public) that works perfectly fine if I call it on postman, even if I type it in the browser, and does not require any authorization or header, but when calling it from my react native app on android simulator it gives me a 401 error, which is strange because I can't find any other way I could possible make it more public, but I'm guessing I'm missing something has anyone had this problem?
Another thing that is strange is when running my react native in web it works fine... it's just on the android simulator
This is my call on my react native!
useEffect(() => {
const fetchAllUpdates = async () => {
await axios
.get(`http://localhost:1337/api/updates`, {
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => {
console.log('Data From Strapi ===>', res);
dispatch(setUpdates(res.data.data));
})
.catch((error) => console.log(`Strapi Error===> ${error}`));
};
fetchAllUpdates();
}, []);
Thank you in advance!
Ok I have figured it, the issue is that the android simulator does not have access to the local server the same way as the browser... so instead of calling
http://localhost:1337/api/updates
One has to find the machine ip address, and we can do that by typing
ipConfig
into the terminal and you will get your ip address then replace the
localhost
with the ip and it works
You should have something like this at the end
http://192.168.7.469:1337/api/updates

React Native with axios - Network error calling localhost with self signed https endpoint

I created service in Visual Studio with Conveyor extension to make it accessible in local network. I installed certificate on my Android device so there is green padlock when calling it in browser and service works fine.
However when calling it from React Native app with axios then i get Network error.
That's my code:
const fetchData = async () => {
console.log('url', `${Settings.API_URL}/location/GetDataByMyIp`);
try {
const result = await axios(
`${Settings.API_URL}/location/GetDataByMyIp`,
);
console.log('result', result);
ipData = {
city: result.data.city,
longitude: result.data.longitude,
latitude: result.data.latitude,
};
} catch (e) {
console.log('error', e);
}
};
await fetchData();
In console i see:
url https://192.168.1.14:45455/api/location/GetDataByMyIp
error Error: Network Error
at createError (path_to_app\node_modules\axios\lib\core\createError.js:16)
at EventTarget.handleError (path_to_app\node_modules\axios\lib\adapters\xhr.js:83)
at EventTarget.dispatchEvent (path_to_app\node_modules\event-target-shim\dist\event-target-shim.js:818)
at EventTarget.setReadyState (path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:575)
at EventTarget.__didCompleteResponse (path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:389)
at path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:502
at RCTDeviceEventEmitter.emit (path_to_app\node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:189)
at MessageQueue.__callFunction (path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:425)
at path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:112
at MessageQueue.__guard (path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:373)
I tried to add this line to AndroidManifest.xml application tag but still have the error
android:usesCleartextTraffic="true"
Some solutions say about adding as 2nd parameter to axios, but it doesn't work with React Native.
new https.Agent({
rejectUnauthorized: false,
});
I tried to call some other service from the internet and then error was gone.
Is there some solution to this? I haven't found anything more. My last idea is to host service on Azure so I'll have properly signed SSL, but i guess it has to be a way to run it locally.
Edit: It works through http

Can't get fetch(url) working in React-Native

I am trying to retrieve the json response from api url using fetch (method : GET) in react-native.
constructor(props){
super(props);
this.state = {jsonData: {}};
}
componentWillMount() {
console.log("inside componentWillMount");
fetch('http://localhost:3000/listData')
.then((response) => {console.log('response: '); return response.json();})
.then((responseJson) => {console.log('responseData: '+JSON.stringify(responseJson)); return this.setState({jsonData: responseJson});})
.catch((err) => {console.log(err)});
}
The api returns data in this format:
{
object: 'list',
data: [...]
}
The api url works via curl. I also tried to run the fetch part of the code standalone using node by installing node-fetch and it printed the responseData properly.
But, in react-native, it doesn't print any of the console log statements inside the then function of fetch nor does it set the state of jsonData.
Could you please tell me what could be the problem? I have been googling around for quite a long time trying to find what could be the issue.
EDIT
I tried the async fetch as follows:
componentWillMount() {
console.log("inside componentWillMount");
this.fetchData().done();
}
async fetchData(){
const response = await fetch('http://localhost:3000/listData')
const json = await response.json();
const data = json.url;
console.log('data'+url);
}
Still, the same issue persists.
I am not able to understand why it works with the facebook url and not my local api url
SOLUTION
Thanks to Michael Cheng for pointing me in the right direction.
I found this link :
https://github.com/react-community/create-react-native-app/issues/154 .
Code Fix:
I just replaced the localhost with my ipv4 address as http://myserveripv4address:3000/listData and it worked.
Version:
react-native#0.50.4
Device : Android
some ideas:
if is iOS, you need the remote url to be https or disable this security feature;
You may need to mark your fetch() as async function;
Try to make an async fetch w/o promise.