2

I've been trying to solve the following problem for a few days now, and it's been driving me absolutely crazy.

I have a (1.2) meteor application, deployed at http://some.application.com:3000. It works great, and does what it is supposed to do. The application uses several packages, the ones that I think are related to this issue are autoupdate and the accounts package (which loads its own bunch of stuff).

Our directive is to turn this webapp into an android app, something we've been told meteor can do "quite easily". On the surface it seems like it's a simple case of meteor run android-device --mobile-server http://some.application.com:3000 --settings settings.json --verbose, however this doesn't do what I expect it to do.

Meteor decides to do the DDP connection on 10.0.2.2 (for whatever reason), and no matter what env variables I set I end up in the same situation.

It's important to note that the application has not been written using the DDP.connect(url) method anywhere [docs], so everything relies on the primary DDP connection (which I suspect might be one of the bigger causes of our problem).

For the record, here is my startup script. I got pretty desperate and added many, many env vars, and haven't had any luck for any combination thereof.

#!/bin/bash
export AWS_REGION=xxx
export AWS_BUCKET=xxx
export MONGO_URL=mongodb://some.application.com:27017/application
export QUEUE_ADDRESS=http://some.application.com
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
export ROOT_URL=http://some.application.com:3000
export DDP_DEFAULT_CONNECTION_URL=http://some.application.com:3000
export MOBILE_DDP_URL=http://some.application.com:3000 
export MOBILE_ROOT_URL=http://some.application.com:3000

# Let's go
meteor run android-device --mobile-server http://some.application.com:3000 --settings settings.json --verbose

Running it locally, on mobile or desktop, (via localhost:3000 with port forwarding, or any other internal IP (10.x.x.x, 192.x.x.x) works absolutely fine. It even works with the remote AWS, Queue and DB.

According to all the documentation the --mobile-server switch should sort things out. It doesn't. I've tried it with and without an =, wrapped in quotes, all possible ways of defining it.

Looking at the <head> of my document I see the following code getting injected

__meteor_runtime_config__ = JSON.parse(decodeURIComponent("%7B%22meteorRelease%22%3A%22METEOR%401.2.0.2%22%2C%22PUBLIC_SETTINGS%22%3A%7B%22verifiedLogin%22%3Afalse%2C%22enableFacebookAuth%22%3Afalse%2C%22enableTwitterAuth%22%3Afalse%2C%22enableGoogleAuth%22%3Afalse%2C%22cdnUrlWithTrailingSlash%22%3A%22http%3A%2F%2Fdev.cdn.some.application.com%2F%22%2C%22ga%22%3A%7B%22id%22%3A%22UA-XXXXXX-1%22%7D%7D%2C%22ROOT_URL%22%3A%22http%3A%2F%2Flocalhost%3A3000%22%2C%22ROOT_URL_PATH_PREFIX%22%3A%22%22%2C%22appId%22%3A%228emj6c37j3fdoz5qmp%22%2C%22accountsConfigCalled%22%3Atrue%2C%22autoupdateVersion%22%3A%222b3acf7aa3ddef802ddf661d3b3986319aad5122%22%2C%22autoupdateVersionRefreshable%22%3A%22b00197cdb5345434d03d9a2503906349ff7854e2%22%2C%22autoupdateVersionCordova%22%3A%223644168d46bc4597d0b2d8c39e366890f6725f52%22%2C%22DDP_DEFAULT_CONNECTION_URL%22%3A%22http%3A%2F%2Flocalhost%3A3000%22%7D"));

if (/Android/i.test(navigator.userAgent)) {
  // When Android app is emulated, it cannot connect to localhost,
  // instead it should connect to 10.0.2.2
  // (unless we're using an http proxy; then it works!)
  if (!__meteor_runtime_config__.httpProxyPort) {
    __meteor_runtime_config__.ROOT_URL = (__meteor_runtime_config__.ROOT_URL || '').replace(/localhost/i, '10.0.2.2');
    __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL = (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL || '').replace(/localhost/i, '10.0.2.2');
  }
}

The UrlDecoded version of that string is as follows

{
    "meteorRelease": "METEOR@1.2.0.2",
    "PUBLIC_SETTINGS": {
        "verifiedLogin": false,
        "enableFacebookAuth": false,
        "enableTwitterAuth": false,
        "enableGoogleAuth": false,
        "cdnUrlWithTrailingSlash": "http://dev.cdn.application.com/",
        "ga": {
            "id": "UA-XXXXXX-1"
        }
    },
    "ROOT_URL": "http://localhost:3000",
    "ROOT_URL_PATH_PREFIX": "",
    "appId": "jfdjdjdjdjdjjdjdjdjjd",
    "accountsConfigCalled": true,
    "autoupdateVersion": "2b3acf7aa3ddef802ddf661d3b3986319aad5122",
    "autoupdateVersionRefreshable": "b00197cdb5345434d03d9a2503906349ff7854e2",
    "autoupdateVersionCordova": "3644168d46bc4597d0b2d8c39e366890f6725f52",
    "DDP_DEFAULT_CONNECTION_URL": "http://localhost:3000"
}

This is strange because I have no entries of localhost anywhere.

Booting the app tells me: App running at: http://site.some.application.com, but no connections are made in the network inspector.

Grepping through the code shows me that the only places where __meteor_runtime_config__ is mentioned is in the autoupdate package.

Further investigation lead me to this issue #3815 which linked to this fix, but after I implemented it (the changes to the autoupdate package) I was still faced with the same problem (although hot code fixes stopped coming through from my local machine)

Even more investigation lead me to believe that the remote DDP server could be changed like this, but unfortunately this solution doesn't work with Cordova.

I tried settings HTTP_PROXY as the comment "unless we're behind a proxy" in the <head> script lead me to believe this might be a quick fix, but I didn't have any luck with this.

I tried removing the accounts package, but have not had any luck in this regard.

Main Question Is there any suggested way to allow a Cordova wrapped Meteor application to connect to an arbitrary server, and allow a DDP connection to same?

The accounts package is (most likely) needed. I suppose auto-updates aren't thaaat crucial, although they do help in terms of not having to regularly release code to the various app stores.

Things I've tried:

  • Removing accounts package
  • Remove autoupdates
  • Modifying autoupdates to point to remote DDP
  • Using the remote-ddp package
  • Forcing __meteor_runtime_config__ overrides
  • Setting a proxy
  • Environment variables
  • And several other thousand things

Related issues (Going back to Jan 2015) are:

Contents of .meteor/packages

aldeed:autoform@=4.2.2
aldeed:collection2@2.5.0
aldeed:simple-schema@1.3.3
aldeed:tabular@1.4.1
autoupdate@1.2.3
biasport:facebook-sdk@0.2.2
blaze@2.1.3
check@1.0.6
edgee:slingshot@0.7.1
iron:router@1.0.12
jquery@1.11.4
juliancwirko:s-alert@3.1.1
juliancwirko:s-alert-slide@3.1.0
lookback:seo@1.1.0
matteodem:easy-search@1.6.4
meteor@1.1.9
meteorhacks:fast-render@2.10.0
meteorhacks:subs-manager@1.6.2
mobile-experience@1.0.1
momentjs:moment@2.10.6
mquandalle:jade@0.4.4
multiply:iron-router-progress@1.0.2
---
internal packages (one of which includes accounts)
---
reactive-dict@1.1.2
reactive-var@1.0.6
reywood:iron-router-ga@0.7.1
session@1.1.1
standard-minifiers@1.0.1
templating@1.1.4
tracker@1.0.9
underscore@1.0.4
underscorestring:underscore.string@3.2.2
utilities:avatar@0.9.2

I can provide the contents of my versions file if you feel that will help.

TL;DR - Is there any suggested way to allow a Cordova wrapped Meteor application to connect to an arbitrary server, and allow a DDP connection to same?

Any help or pointers around this issue would be much appreciated. Please let me know if there is any other information you may need to assist in this regard.

Many thanks

Issue On Github

darryn.ten
  • 6,784
  • 3
  • 47
  • 65
  • Have you tried a blank app with just those settings? Works for me with `meteor run android-device --mobile-server http://some.application.com:3000`. – MasterAM Oct 19 '15 at 21:40

0 Answers0