Deploying server for Meteor Cordova App

I’m building a hybrid app with Meteor and Cordova. I’m stuck trying to get my Cordova apps to connect to my production server. Everything runs smoothly in my local dev environment and my mobile apps have no trouble to connect to the local server. It also works when I deploy to meteor.com. It only falls apart when I try to use my own server.

I tried to use app versions provided by meteor build --server http://my.server.ip as well as meteor run android-device --server http://my.server.ip. My server meteor server runs on an Ubuntu VM and I tried running it with and without Nginx.

In all cases I have no trouble accessing my app via the web but both apps just log cordova.file.dataDirectory is null and don’t connect to the server. Is there anything else I need to do or does anyone have a guide for a working configuration?

I’ve been stuck at this same place, for about as long as you have. Also on Ubuntu, but not VM, native 14.04. I just posted a similar thread and found your thread right before I clicked “Create Post”, posted it anyway because of the slight differences (no VM, local desktop connected to router sending wifi to phone).

Did you ever make progress?

Do you have whitelisted the app server’s URL? https://www.yauh.de/the-illustrated-guide-to-mobile-apps-with-meteor/#hardware

Did anyone find a solution for this problem?

I am using a Cloud9 workspace, with a URL like

 https://foo-bar.c9.io/

I have tried running the iOS simulator, pointed at this server, like this:

meteor run ios-device --mobile-server https://foo-bar.c9.io/

From the logs and from the app itself in the simulator, I can see that it is still clearly running the server on on OS X.

Actually the logs looks the same, just as if I never included this part:

--mobile-server  https://foo-bar.c9.io/

… and yes, in my mobile-config.js, I have whitelisted:

App.accessRule('*');

Using meteor run with --mobile-server https://foo-bar.c9.io will still start the local server, but the mobile app should connect to foo-bar.c9.io. Isn’t that the case?

Right, I get the message that

=> App running at: http://localhost:3000/

Which makes sense, because obviously for the iOS simulator to work, the computer has to somehow serve up the software.

But clearly the simulator is using the local OSX database & server, not the server I have specified with

--mobile-server  https://foo-bar.c9.io/

I can tell this simply by looking at the data that is being served up in the app. It’s the database from my local machine, not from the C9 server.

Is there some kind of debugging I should do or something I should look for in the logs to try to figure out what is going on?

And am I right that the only configuration that is necessary is this flag:

--mobile-server

And allowing the cordova app to access external websites with:

 App.accessRule('*');

thanks!

Also, does it matter somehow that this server

https://foo-bar.c9.io/

Is a development server, and maybe doesn’t have some kind of production flag set on it? I don’t see why that should matter – I mean, this site is publicly accessible…

If you want to make sure the URL specified with --mobile-server is passed to the app, you can have a look at www/application/index.html in the generated Xcode project. There should be a line that sets configuration options that starts with __meteor_runtime_config__ = JSON.parse(decodeURIComponent, ...). The easiest way to check this is to copy everything from JSON.parse to a browser debug console so you get an object back that you can expect.

I suspect the server is being set correctly however, and the problem is on the server-side. Even if the app connects to right server at first, it might reconnect immediately to the wrong one after a Hot Code Push. This is because subsequent updates delivered through Hot Code Push replace the initially bundled index.html with a freshly generated one, so the server should also be configured with the right connection URL.

Using meteor deploy takes care of setting these values automatically, so there is no need to specify anything in that case. But when deploying on your own server, you have to make sure to set at least the ROOT_URL environment variable (DDP_DEFAULT_CONNECTION_URL defaults to the same value). For Meteor Up for example, you can configure this in mup.json.

I have made some progress, though I still must admit I am in the land of confusion.

First, I do see this as you describe, and in every case it does seem to be pointed to the right server:

 __meteor_runtime_config__ = JSON.parse(decodeURIComponent, ...)

Both the iOS Simulator and an actual iPhone 6 refuse to connect with my development server at:

https://foo-bar.c9.io/

Both the physical and simulated device connect to my OS X box instead.

To try something new, I did the command

meteor deploy foo-bar.meteor.com

Following this, I can connect from the physical iPhone 6 device to the newly deployed foo-bar-meteor.com server.

However, the simulator still uses the local OS X server.

So to sum up, I can’t yet connect to my development server, or to any server from the iOS simulator. I can however connect to the deployment server from an iOS device…

Are you specifying --mobile-server foo-bar.meteor.com when running on both the device and the simulator? I don’t see why only the device would be able to connect to the deployed server. Are you sure you’ve installed the new version on the simulator?

The reason the server deployed using meteor deploy works is because it configures the connection URL automatically. Have you tried setting ROOT_URL on your c9.io server, as described in my reply above?

You’re right. Setting the ROOT_URL environment variable does the trick. I had to stop and restart the simulator a few times, and also delete the iOS application from my device and allow Xcode to reinstall it, but now I have both the simulator and the device pointed to my c9.io server. Thanks.

I ended up here to search for a solution for a similar issue.

What seems to be happening to us, is that after you change the server, the app still retains all the old bundle and is still using it, both to decide what code to run and to what server it should be connected to.

I suspect that what did the trick to you was just deleting the app. But both updating from app store and simply running the app won’t affect the fact that it will still be connected to the old server (the local one in the OP case).

This is a major issue for us, as the same is happening for apps in production that need to be updated. It’s entirely possible that we are doing something wrong, in which case I’ll appreciate any pointer.

I only realized this was going on a few weeks ago, but it turns out that if there are existing hot code pushed assets, these will be used instead of the ones bundled with an app update. As you discovered, the issue with that is that it means there is no way to change the server URL via an update. I’m afraid the only solution is to delete and reinstall the app.

When you say this also affects apps in production, do you mean you’d like to change the server URL for these as well?

I’m currently working on an updated file serving and hot code push plugin and will make sure to include a fix for this.

2 Likes

Yes, I mean that we should change the server for an app currently in production (.com over .org), and that we fear the simple update from the app store wouldn’t do the trick. At least, testflight seems not to be doing it, as the user still sees the old app unless he deletes it manually first.

Anyhow, thanks a lot for the work you’re doing :smile:

We were digging trough the code to see if we could also understand the behaviour, but I’m not sure where a hook for the native update of the app could lie - not being a native developer I’m not even sure if there are goods methods for that. If that existed we could simply delete the downloaded bundle or perhaps just the version file from the user data directory whenever the user installs a new version.