Cordova app (Android) not reloading after hot code push with deployed app

Hey @martijnwalraven!
As a meteor-head, I want to thank you all at MDG for your hard work to bring us 1.3

I just upgraded my mobile app to find out if it would solve my previous problem.

I am able to get the HCP working with a published Cordova app built with --server option set on a locally running instance (I had to build the app first, and then run meteor with a target specified as pointed out here).

After deploying the app in production, I can see the same behaviour as before, web client gets refreshed, no cigar for Cordova.

Values for ROOT_URL is set alright in runtime config, I even get a value for autoupdateVersionCordova.

Pls, halp.

2 Likes

Are both the app and your server on Meteor 1.3?

Can you check if the asset manifest is served at /__cordova/manifest.json on your production server?

Any error messages either in logcat or with Chrome remote debugging?

I forgot to mention __cordova/manifest.json gets served.

BUT, opening logcat (thx for the tip) got me:

Error: Skipping downloading new version because the Cordova platform version or plugin versions have changed and are potentially incompatible

cordova --version gives 6.1.0

Trying to update incriminated plugins… Getting back at you after that.

Nope, still no luck with my issue :cry:

I tried removing every single cordova plugins (including crosswalk), I still get the same error.

The issue is that hot code push can only update JavaScript code, so to protect against situations where updated code depends on (versions of) plugins that are not in the native app bundle, we block hot code push when either the platform version or the set of plugins have changed.

You may have installed or updated plugins yourself, but Meteor 1.3.1 also updates some plugins included by default. So if your server is running Meteor 1.3.1 and your app was build using Meteor 1.3, hot code push will be blocked until you update the app on the app store.

Is this the case, that hot code will be blocked for every minor update to Meteor, if the app and server are not running the same version?

This will be a huge problem for us. I can see the need to do this between 1.2 and 1.3 as it was a major update to mobile with lots of breaking changes. However, this is will be untenable for us if we have to re-submit to app store for every minor bug fix release of Meteor. I can potentially see the need to block hot code push if cordova plugin versions change, but not for Meteor IOS/Android versions.

Please clarify, thanks.

It is not about the version of Meteor per se, so this shouldn’t happen for every minor update. But we did update some of the versions of default plugins in Meteor 1.3.1, so that is what triggered this.

I updated my project to 1.3.1 today and I can see in __meteor_runtime_config__ that this is what’s running in production…

Unless absolutely required because of a major blocking bug in any of the default plugins bundled with Meteor I’d like to suggest that we NOT update these plugins between minor (x.x.x) releases and save these changes for major releases (x.x.0) going forward.

In addition, this should be documented in the release notes and history as this type of change is really a “breaking change” for any deployed mobile app.

Thanks again for all your hard work and great improvements with Meteor mobile.

3 Likes

@martijnwalraven i have a very similar issue while developing locally. The manifest file seems to not be served when i start the server with a simple

meteor run --settings “config/settings-local.json” --mobile-server “localIp:3000”

as soon as i run with ‘meteor run android-device’ the manifest file is served. But sometimes i want to just start the app via android studio to test some stuff. This was different some time ago and it think it makes sense to include server the manifest whenever there is a mobile-server flag and/or there are ios and android as platforms included.

http://MY.LOCAL.IP:3000/__cordova/manifest.json

Is there a special flag we could use to fix this while developing right now?

@nerdmed: This was actually a deliberate change made as a result of this issue, because people wanted the ability to run the app in the browser without building the Cordova bundle. A few people have noted they preferred the previous behavior, so maybe we need to somehow make this configurable.

@martijnwalraven ok i see, i dont know how much time you have right now for this. I could work on a PR to make it customizable. I think the options are:

  • Enviroment variable
  • Detect --mobile-server Flag (why should i use the mobile server flag when running on browsers only)

I think detecting the mobile server flag makes most sense. What do you think?

I was just scouting around the forums to find out why my app wasn’t hot code pushing, them came across this post. A big +1 to not make any cordova updates or anything that would disable hot code push in minor versions, this caused us some headaches today wondering why our app wasn’t updating.

@markoshust same here, all my developers were going crazy because of this - maybe i will find the time for a quick fix on the weekend

@martijnwalraven I have been running into similar problems ( Error: Skipping downloading new version ... ) in development. While we’re not in production yet I can see this causing issues for us regardless of how Meteor’s own cordova dependencies are handled going forward.

I can understand the point made by @skirunman in regards to not updating plugin dependencies unless necessary but at the same time why should we limit updates to cordova components based on this? In our case we also have our fair share of plugin (some in-house) dependencies that will likely change frequently but will generally remain compatible.

Do you think it would make more sense to provide a means to override this compatibility check in some way (perhaps thru mobile-config.js) to define some type of compatibility level (i.e. a-plugin 1.0.0 & 1.0.1 are compatible) which would be generated in the manifest and taken into account during this check? Meteor itself could even inject its own pre-defined compatibility maps for said major version if it makes sense but beyond that it would be up to us to decide and define what is considered compatible and what isn’t in regards to cordova upgrades.

Thanks for all your awesome work!

1 Like

Really I don’t get any of this…

This is from production manifest after building on final server

manifest: [], version: "fcff1a30ae87438d1f849d8c31522ba775768e4a", cordovaCompatibilityVersions: { android: "3c917ef06da10ba0bd5ca565c630423e423d14e5", ios: "bb2f370767fa894b9135fa8213e1a46e4bc17aa2" }

and this what my local manifest shows when I run meteor --production (–android-device so the manifest is served…)

manifest: [], version: "0c7e8aae38dba77f94a7333cdb4f2aeac5c8db67", cordovaCompatibilityVersions: { android: "61029d6a87fc59dfe343a3c0486f392ebe295113", ios: "4ba03a4d551df0557396260438c3d791f05f7a44" }

On my local server, the meteor version is updated, cordovaCompatibility stands, that makes sense, and updates get pushed all right.
When I build my app for Cordova locally, it gets assigned a cordovaCompatibilityVersions.android that should reflect what that version will be on production server.

My question is simple:

if I build my app locally, say for Android, and then push my code to be handled by the build stack on the server, which then produce a NEW build, with a new cordovaCompatibilityVersions.android, how the hell can those versions match in the first place?

Sorry if I sound desperate. That’s because I am :tired_face:.

Are your server and your development machine running the same version of Meteor? There have been some updates to plugins in 1.3.1, and these affect the cordovaCompatibilityVersions.

Other than that, the results should be the same. The hash is based on the exact versions of the Cordova platform and plugins used in your app.

What do you mean by build stack on the server? I assume you run meteor build?

Yup, 1.3.1 on both sides.

Meteor app is published using Scalingo node buildpack with the --server-only option set to true to build the cordova.web target, just like we talked about…

I uninstalled my own local Cordova via npm, just to be sure.
meteor build logs say Android project created with cordova-android@5.1.1.
I can’t say for sure if there’s a difference in Cordova version once deployed, but the meteor version is definitely the same.

And meteor_runtime_config gives me

on server:
appId:"1yb4n7j1dgujxeg48ddu" autoupdateVersion:"17296cfd7afc77a031d0460b67db848d2b77982c" autoupdateVersionCordova:"42854b4dd77a1e2d02d1521e685d561c6e727a21" autoupdateVersionRefreshable:"18ed05fde50e6f92d9f8ca65f1119c3dc66d5671"

Inspecting the webview of the mobile app:
appId: "1yb4n7j1dgujxeg48ddu" autoupdateVersionCordova: "598ce839cf96aa4e2b890c6a598db1fd2ce6ad6c"

@martijnwalraven any updates on this issues? Its really a pain while developing for native. I think the tradeoff between speed and breaking the developer experience for a lot of mobile developers should be clearly towards making things work. I would really appreciate reverting the change that is causing this issues. I assume that this did not happen with one of the 2 patches that were released the last days.

@nerdmed: While there have been plugin changes between 1.3.0 and 1.3.1, there have been none in further patch releases. So as far as I know hot code push should work, and if it doesn’t we should find out why.

Another question is whether the current compatibility policy is too strict or whether we need to implement some kind of manual override. Basically, any change in native code (platforms and plugins) could trigger an incompatibility with user JavaScript code, so I implemented a conservative strategy of always blocking hot code push when the versions don’t match.

1 Like