Calling locally hosted server from Expo App
Asked Answered
P

17

52

I am creating a react-native app and one of the components I have created contains a property which is populated through data coming from an http request.

Right now I am hosting the server from my laptop, however I am testing the app on my phone using the Expo app. Since these are two separate devices, the http://localhost:3000 calls are not working and thus I can not tell whether or not my component is properly working.

Is there any way for me to run the server on my laptop and set it up so that the http requests from within the Expo app reach the server?

Perez answered 21/11, 2017 at 16:17 Comment(1)
did you get this working?Furnishings
L
47

You can get the IP address at runtime using the Expo manifest:

import Constants from "expo-constants";
const { manifest } = Constants;

const api = (typeof manifest.packagerOpts === `object`) && manifest.packagerOpts.dev
  ? manifest.debuggerHost.split(`:`).shift().concat(`:3000`)
  : `api.example.com`;

This will set api constant to the address of your local development machine in development mode and to whatever address you use in production. Note that apps deployed through App Store / Play Store seems to have packagerOpts undefined. That's why we have additional typeof condition. In that case we assume it's production build.

More about the manifest here: https://docs.expo.io/versions/latest/workflow/how-expo-works/#expo-development-server

Longdrawn answered 9/3, 2018 at 16:27 Comment(4)
Note that this will only work if you serve your app over LAN. Here is a feature request to enable this for tunnels as well: expo.canny.io/feature-requests/p/tunnels-to-additional-portsLongdrawn
this Work for me, It is important to mention that it is necessary to add http:// before the IPResorcinol
Constants has been moved to react-native-unimodules in recent versions.Biernat
Thanks for your comment @borislemke. I did a quick research and according to docs.expo.io/versions/v36.0.0/sdk/constants expo-constants is still the module that exposes Constants.manifest. Are you saying it won't work this way? I don't use Expo anymore so it's difficult for me to actually test it.Longdrawn
F
33
import Constants from "expo-constants";

const { manifest } = Constants;

const uri = `http://${manifest.debuggerHost.split(':').shift()}:4000`;
Frost answered 8/7, 2019 at 23:33 Comment(2)
saved me precious time of my lifeUnemployed
use @Emi solution below for those of you coming after debuggerHost got deprecatedNakasuji
J
18

The solution using debuggerHost stopped working for me after setting EAS Update, so I started doing that instead:

const uri =
  Constants.expoConfig?.hostUri?.split(':').shift()?.concat(':8080') ??
  'yourapi.com';

In case you are using TS, for some reason hostUri is not typed but the prop exists.

Juniper answered 17/3, 2023 at 23:45 Comment(3)
This is the most up to date answer, the ones using manifest are deprecated nowWhiz
Why is this answer hidden like this, it should be on a big red banner on the Expo website. ThanksClosing
It didn't work on iOS, Expo 51, without http://Priebe
H
14

You should replace the http://localhost:3000/ address with the ip address of your computer.

On windows, open a prompt and type ipconfig, check the line of your network interface and get the address IPV4, should look like 192.168.1.20. Then you can make your calls with fetch and an url looking like htt://192.168.1.20/routname.

By the way, your computer (server) and your device must be on the same local network. Wifi and lan shares the same network.

Hautemarne answered 21/11, 2017 at 16:32 Comment(2)
Lifesaver.!!!!!!!!. Also, use the port number like this. 192.168.1.20:3000/routnameOverreach
Thanks a ton for your response, in this era of GEN-Z i was trying to solve my problem through chat gpt and see, where i am getting answer, as always a relliable source.Raposa
L
6

To add to Tadeusz's answer, in the current version of Expo (I'm on 32.0.0 right now), you would import Constants rather than Expo (even though the constants are referenced in the docs as Expo.Constants.manifest), so it would look like

import { Constants } from 'expo';
const { manifest } = Constants;

Also, prepending the generated address with the protocol seems to be a must to make it all work.

Lemus answered 10/1, 2019 at 23:28 Comment(0)
J
5

For the life of me, I could not get any solution that I found (including all the ones on this page) to work. I spent a couple days trying. Finally, I just gave up and worked around this whole problem by using localtunnel and exposing my service running on localhost:8080 to the web. Worked first try when calling it from my expo app. Maybe not the greatest long-term solution, but not so bad, either. I hope this helps someone else!

Jamestown answered 3/6, 2019 at 15:34 Comment(0)
F
4

Tad Lispy's solution worked for me. But I formatted it a little bit differently.

I also added support for react-native-web, using the document object.

import Constants from "expo-constants";

//const inProduction = manifest.packagerOpts == null;
const inProduction = process.env.NODE_ENV === 'production';
const inExpo = Constants.manifest && Constants.manifest.debuggerHost;
const inBrowser = typeof document !== 'undefined';

export const apiDomain =
    inProduction ? 'mywebsite.com'
  : inExpo ? Constants.manifest.debuggerHost!.split(`:`).shift()
  : inBrowser ? document.location.hostname
  : 'unknown';

console.log('apiDomain:', apiDomain);

const protocol = inProduction ? 'https' : 'http';

const apiUrl = `${protocol}://${apiDomain}/...`;
Fancie answered 12/12, 2021 at 11:23 Comment(0)
W
2

I tried some of it and it didn't work, finally simply used ngrok

Whish answered 1/10, 2020 at 20:13 Comment(0)
R
2

Works with React-Native app on iOS physical device that's running separately from your computer, but is calling a localhost API:

Your API call before may have looked like this: http://localhost:3000/api/user/login

On windows, open up your command prompt (press the windows key on your keyboard, type cmd, press enter; this should open it), then enter ipconfig into your command prompt and press enter.

This should give you a big list of data. Scroll down until you you see this field: IPv4 Address...... Take it's value from the right side (something like this: 192.168.1.33).

Next, plug this number into your API call like so: http://192.168.1.33:3000/api/user/login

Make sure you and your device are both using the same wifi network. This should now work.

Summary:

Old API call: http://localhost:3000/api/user/login

New API call: http://192.168.1.33:3000/api/user/login

Rianon answered 25/5, 2022 at 11:4 Comment(3)
Hi, in production, what IP address should i use?Barcroft
@Barcroft The real address that you're hosting on. For example: myrealdomain.com/api/user/loginRianon
Hi and thank you for getting back to me. My problem is i want to show an HTML file. I have done this you requested but now the url doesnt open in my react native webview but opens in my browserBarcroft
C
2

If anyone is running into the same issue and nothing is working, just use ngrok.

npm install -g ngrok

Sign up on https://ngrok.com/ and get an authentication key. Add it to your config:

ngrok config add-authtoken <authentication key>

Now forward to whatever port your local server is listening on:

ngrok http 8080

It will give you the endpoint to use, e.g.

https://d1b3-2a02-c7c-67d5-3200-9135-ah8c-7f38-2h9f.ngrok-free.app

Simply replace your endpoints with this and both the Expo emulators as well your as your physical device will now be able to talk to your local server.

Carrelli answered 29/5, 2024 at 16:8 Comment(0)
F
1

One another easy way. First you need to on Mobile HotSpot and connect to laptop using Mobile HotSpot. Then check you ip assign to your computer and replace api url http://localhost:80/ address to http://192.168.5.43:80/ in react-native source where you use.

Replace port 80 to your api server port no.

Make sure you have open server port (80) in firewall in laptop.

Test api in android rest-client https://play.google.com/store/apps/details?id=com.sn.restandroid app (url : http://192.168.5.43:80/api)

Fyn answered 7/3, 2018 at 11:43 Comment(0)
S
1

How to call a locally hosted server from Expo is explained in details from Divyanshu Singh with some solutions:

  • By using ngrok or localtunnel
  • By running the server on 0.0.0.0 (this solution worked for me)

https://dsinecos.github.io/blog/How-to-call-a-locally-hosted-server-from-expo-app

Sanderlin answered 26/5, 2021 at 2:23 Comment(0)
V
1

Quick and easy solution that works straight forward!

Localtunnel docs

  1. Install Localtunnel globally (requires NodeJS) to make it accessible anywhere:

npm install -g localtunnel

  1. Start a webserver on some local port (eg http://localhost:8000) and use the command line interface to request a tunnel to your local server:

lt --port 8000

  1. You will receive a url, for example https://gqgh.localtunnel.me, that you can share with anyone for as long as your local instance of lt remains active. Any requests will be routed to your local service at the specified port.
Violative answered 25/12, 2021 at 12:38 Comment(0)
L
0

[In addition to the above] If using Laravel artisan serve, pass in your computer ip as host parameter:

php artisan serve --host 192.168.0.19 --port 8000
Lettyletup answered 12/5, 2021 at 20:51 Comment(0)
R
0

Doesn't know why but this particular IP address is somehow related to the Android Emulator. I tried the above solutions (Machine's private IPv4) but that also didn't work. So, if someone's developing inside an Android emulator then you can use this IP address.

http://10.0.2.2

And don't forget to add the PORT number of your localhost server.

Roguish answered 29/10, 2021 at 18:20 Comment(0)
D
0

In my project I normally get the local dev server via config so I adapted @tiagob's answer to just patch the localhost address:

let uri = Config.host;
if (uri.includes('localhost') && manifest.debuggerHost)
  uri = uri.replace(
    'localhost',
    manifest.debuggerHost.split(':').shift()
  );

In production the config won't include localhost so this code will just return the unmodified configuration variable.

Dykes answered 3/2, 2022 at 1:1 Comment(0)
P
0

With Laravel, the pera response may help...

Start your server with this commands: php artisan serve --host 192.168.0.19 --port 8000

replace '192.168.0.19' with your ip address

Polemics answered 2/3, 2024 at 14:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.