[SOLVED] Mup + android Hot Code Push not working

I’m having an issue getting Hot Code Push working on Android (haven’t tried iOS) in production using mup.

Working in development works well via meteor run --android-device. The app opens on my USB connected Android phone, I make a small change to the html and the android device updates almost instantly.

Then I deploy with mup using the settings below. Goes OK. Then I sign & align the apk and copy it to my phone, install and it works OK.

Then if I make another small change to the html and re-deploy via mup, web clients update OK, but the Android app never receives the HCP. Even it I leave it for a while, then kill and reload it, it still has the same old html.

What could I be doing wrong?

I’ve opened an issue on meteor-up here.

mup config:

module.exports = {
  servers: {
    one: {
      host: 'virtualinout.com',
      ...
    }
  },
  meteor: {
    name: 'virtualinout',
    path: '../',
    docker: {
      image: 'zodern/meteor:root'
    },
    servers: {
      one: {}
    },
    buildOptions: {
      //serverOnly: true,                     // I've tried all permutations of each of 
      server: 'https://www.virtualinout.com'  // these lines commented or not
    },
    env: {
      ROOT_URL: 'https://www.virtualinout.com',
      MAIL_URL: ...
    },
    enableUploadProgressBar: true,
    deployCheckWaitTime: 300
  },
  proxy: {
    ...
  },
  mongo: {
    version: '3.4.1',
    servers: {
      one: {}
    }
  }
};

https://www.virtualinout.com/__cordova/manifest.json :

cordovaCompatibilityVersions: {
   android: "b4255a094c2d1bcc617f2a18fbfab66d768408f9",
   ios: "43bc6556084ea4690d53630ba43b8f4d7fc8433b"
}
version: "38700ae8ff0e18e5afb5461237aedb29f7a1de8a"

Note that the android version “b4255…” was the same before and after the html change and redeployment.

https://www.virtualinout.com/ __meteor_runtime_config__ :

autoupdateVersion: "2e2c4778578a0c6a05c59d794a6766435cabb35a",
autoupdateVersionCordova: "38700ae8ff0e18e5afb5461237aedb29f7a1de8a",
autoupdateVersionRefreshable: "3a18e34b84687acc299fd1e63121358697766065"

Any help greatly appreciated!

Why don’t you use the env variables for Cordova hashes instead of mup vars?

I’m not SETTING any environment variables for build hashes. The hashes above are the build hashes as reported by https://www.virtualinout.com/__cordova/manifest.json and https://www.virtualinout.com/ __meteor_runtime_config__.

I included these in my post to show that cordovaCompatibilityVersions.android didn’t change between builds, so I would expect the HCP to work. I’m not sure what the hashes in https://www.virtualinout.com/ __meteor_runtime_config__ mean.

Since my original post I’ve got the iOS app built, and HCP works find on iOS. It’s still not working on Android.

Looking at the android logs when I open the production app yields:

3820 E MeteorWebApp: Download failure
3820 E MeteorWebApp: com.meteor.webapp.WebAppException: Error downloading asset manifest
3820 E MeteorWebApp: 	at com.meteor.webapp.AssetBundleManager$1.onFailure(AssetBundleManager.java:97)
3820 E MeteorWebApp: 	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:140)
3820 E MeteorWebApp: 	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
3820 E MeteorWebApp: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
3820 E MeteorWebApp: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
3820 E MeteorWebApp: 	at java.lang.Thread.run(Thread.java:776)
3820 E MeteorWebApp: Caused by: java.net.ProtocolException: Expected ':status' header not present
3820 E MeteorWebApp: 	at okhttp3.internal.http.Http2xStream.readHttp2HeadersList(Http2xStream.java:266)
3820 E MeteorWebApp: 	at okhttp3.internal.http.Http2xStream.readResponseHeaders(Http2xStream.java:149)
3820 E MeteorWebApp: 	at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
3820 E MeteorWebApp: 	at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
3820 E MeteorWebApp: 	at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)
3820 E MeteorWebApp: 	at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
3820 E MeteorWebApp: 	at okhttp3.RealCall.getResponse(RealCall.java:241)
3820 E MeteorWebApp: 	at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
3820 E MeteorWebApp: 	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
3820 E MeteorWebApp: 	at okhttp3.RealCall.access$100(RealCall.java:30)
3820 E MeteorWebApp: 	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
3820 E MeteorWebApp: 	... 4 more
3714 I chromium: [INFO:CONSOLE(75)] "Error: Error downloading asset manifest", source: http://localhost:12768/bb6d78a87664c0a708cb6e02b8b4a85f31fcefa7.js?meteor_js_resource=true (75)

This suggests that come kind of :status header is missing on the manifest, but this is only a problem for Android.

Googling those errors finds a couple of other Meteor users with the same problem, but no resolutions: here on Stackoverflow, using MUP and here on github.

Googling just java.net.ProtocolException: Expected ‘:status’ header not present reveals quite a few non-Meteor references to this problem. HTTP/1.1 on nginx comes up a couple of times.

I’ve also created a post on the meteor forums.

Does this shed any light on the problem?

The manifest URL for mobile app is ROOT_URL/__cordova/manifest.json

Make sure that URL can be accessed by your proxy (e.g. check /var/log/nginx/error.log if you are using defaults for nginx). The __cordova in the URL is used by the meteor webapp plugin to download the files that need updating and your website config may be having issues with it

This is a real head scratcher. I don’t think you’re doing anything wrong. Fork the appropriate packages that build the Android plugin and try the fixes here: https://stackoverflow.com/questions/46807237/protocolexception-expected-status-header-not-present

Hashes are changing with mup deploy. You need to set METEOR_CORDOVA_COMPAT_VERSION_IOS and METEOR_CORDOVA_COMPAT_VERSION_ANDROID environment variables. Even though there is no change in cordova plugin versions mup deploy still re-hashes compatibility version. Also you may need METEOR_CORDOVA_COMPAT_VERSION_EXCLUDE

Hi @baris. The hashes are not changing, the problem is that the app cannot download the manifest file from the server due to a problem between okhttp and nginx-HTTP/2. If the hashes are changing then the applogs report that the hash has changed: Skipping downloading new version.... Instead the applogs report Error downloading asset manifest... Expected ':status' header not present.

Hi @doctorpangloss. I’m not yet sure how to update just the appropriate packages or which packages to update. However, I think I’ve made progress by updating to meteor 1.6.2-beta.21. Now, when I run the app on my phone via USB with --mobile-server https://www.virtualinout.com the applogs show:

com.meteor.webapp.WebAppException: Skipping downloading new version because the Cordova platform version or plugin versions have changed and are potentially incompatible

Which at least shows that its been able to download the manifest.

Next I need to try a fresh deployment to a staging server to see if HCP works when the hashes haven’t changed… Then I can try to isolate which individual package needs to be upgraded (maybe webapp or cordova-plugin-meteor-webapp). The fixes in the link you sent suggest recompiling okhttp and retrofit, but I’m not sure how to do that.

Will keep you posted…

I’ve fixed it! I narrowed it down to cordova-plugin-meteor-webapp. Upgrading only this plugin with:

meteor add cordova:cordova-plugin-meteor-webapp@1.6.0

Then redeploying to a fresh staging server, installing the app, making a HTML change and redeploying with serverOnly: true (mup) caused the app to instantly receive the hot code push.

Thanks for your help.