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

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

@martijnwalraven is it possible for you to not block hot code push releases for custom cordova plugins that we install?

there are many situations where we want to release a new code update with a hot code push. it does involve a new cordova plugin, however there is also functionality we are releasing that doesn’t require this new plugin, and/or the plugin is optional (for example, let’s say ‘dark keyboard’). we don’t want our entire hot code push blocked because the new version of our code says that we have this plugin, which really isn’t needed.

as far as being worried about cordova-specific code causing an app to crash, i think that should be left up to the implementer to decide. for example, every single place there is cordova code in my app, i wrap it in code like this:

import {Meteor} from 'meteor/meteor';
import {_} from 'meteor/underscore';

const hideKeyboard = () => {
  if (Meteor.isCordova
    && _.isObject(cordova.plugins)
    && _.isObject(cordova.plugins.Keyboard)
  ) { 
    cordova.plugins.Keyboard.close();
  }
};

export default hideKeyboard;

so let’s say i release new code now containing the Keyboard cordova plugin, i really don’t want this hot code push blocked, because it will not crash my app because of this code.

if you want to continue blocking, it would be really nice to expose the ability to not block hot code pushes in this event from the mobile-config file or something similar.

another situation where this applies is let’s say i have a major release coming up, and i submitted it to the app store and it’s awaiting approval. if i push the related code out to production, anyone who downloads the current version of the app that is live in the app store never gets any hot code push updates, because the most recent push fails because of the cordova block. however, when apple reviews it, it can get denied because the server code isn’t up to date, as it’s possible some new function calls don’t exist yet on the server because we can’t push out this update (because we still want users to get most recent hot code push for their app version).

1 Like

@markoshust: I think the solution is to allow developers to override cordovaCompatibilityVersions (the same way we allow AUTOUPDATE_VERSION to be defined manually). This way, you could set it to the current value when adding new plugins so hot code push won’t be blocked. Could you open a GitHub issue for this?

1 Like

+1 this would be awesome! Spent nearly two days tracking the same issue (on iOS) down to a tiny cordova version bump.

doesn’t look like an issue was already opened for this, opened one as: https://github.com/meteor/meteor/issues/7030

1 Like

This is all amazingly helpful to know, and I agree with @skirunman it should be documented as a breaking change. I have thousands of cordova clients out on Meteor 1.2 and I’m very concerned - you know how lax people are with updating their apps via their appstore. It keeps me up at night worrying about having to support ancient client versions.

How can I reliably show some kind of ‘Upgrade via App Store Please’ dialog to older clients?

Also, I just want to confirm - would hot pushes stop ENTIRELY for Meteor 1.2 clients? So for example when my server is on 1.3, a 1.2 cordova client which is many pushes behind would be stuck there, and not be updated to the latest 1.2 code?

Compulsory polite and supportive notice: Despite frustration at this issue, thanks for the great work MDG! :grinning:

@denisbabineau thank you for creating the ticket, I somehow didn’t get updates to this forum post.

where is the documentation for AUTOUPDATE_VERSION? I didn’t even know this existed. the suggested from @martijnwalraven seems like that would work, however need to see the documentation/code on this to see how to implement.

found some basic docs referring to AUTOUPDATE_VERSION in the internal autoupdate package. I tried digging around a little - autoupdate override happens [cordova/builder.js] but the cordovaCompatibillityVersion looks like it’s getting set in isobuild/bundler.js as a hash of all package versions and the cordova version.

It looks like if you wanted to override, i thiiink you’d be able to by change const hash in bundler.js to below - might give this a shot later myself…

const hash = process.env.CORDOVA_COMP_VERS || WebAppHashing.calculateCordovaCompatibilityHash(
            version,
            this.cordovaDependencies); 
1 Like

Hot code push not working on iPhone
So I have the app working perfectly on version Meteor 1.2.2-faster-rebuilds.0 - Hot code push working on both android and ios . Before submitting the app to the stores , decided to take advantage of the latest meteor and ported the app. Should admit , migration was Smooth! But the hot code refresh does not work .

To keep things simple all i do is copy the entire meter project folder on to the server ( ubuntu 14.04 on google compute engine )and then run it on server with the root_url , mongo url , set up with the --mobile-server option . App built on my local dev machine ( mac) connects to the server just fine and any client updates get refreshed - Worked flawlessly with 1.2.2 With 1.4…1.1 latest build the same does not work … hot code push is not working…

What are the steps to debug hot code push ? information to debug seems to be scattered in multiple threads … is there a single doc or can someone help me with debugging this ?
Thanks very much

1 Like