Upgrading from meteor 1.2 to 1.3, mobile app does not receive hot code push from server

I upgraded meteor from 1.2 to 1.3 and hot code push on mobile apps (both for iOS and android) is not working. The apps are not receiving any changes made to the javascript/html file from the server. But it works just fine on desktop browser.
I get the following error on android logcat console
E/MeteorWebApp: Download failure
_ com.meteor.webapp.WebAppException: Error parsing asset manifest_
_ at com.meteor.webapp.AssetManifest.(AssetManifest.java:80)_
_ at com.meteor.webapp.AssetBundleManager$1.onResponse(AssetBundleManager.java:112)_
_ at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)_
_ at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)_
_ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)_
_ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)_
_ at java.lang.Thread.run(Thread.java:841)_
_ Caused by: org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject_ _ at org.json.JSON.typeMismatch(JSON.java:111)_ _ at org.json.JSONObject.(JSONObject.java:158)_
_ at org.json.JSONObject.(JSONObject.java:171)_
_ at com.meteor.webapp.AssetManifest.(AssetManifest.java:39)_

Hot code push was working previously with 1.2. on both iOS and android apps and desktop browser.

Is your server also running Meteor 1.3? Hot code pushes from 1.2 to 1.3 (or the other way around) are not supported.

yes it is . I used meteor build command with –server=http://192.168.0.12:3000
and meteor is running with
meteor --mobile-server=http://192.168.0.12:3000

where that is the ip of my desktop.

Hmmm, could you try to download http://192.168.0.12:3000/__cordova/manifest.json and post the result here?

That file does not seem to exist . On browser it shows a not found page of the app. Will it be somewhere in app folder(meteor) where I can access it.

Ah, that explains it! Meteor 1.3 won’t serve the Cordova-specific code unless you run it with a mobile target, like meteor run ios-device.

Cool ! it works now on android device.

But what happens if we build apk from the android folder generated from meteor build command using the actual server(not on the desktop) where the app is hosted. This apk will be on google play store. So will the apk downloaded from there be able to get hot code push from the hosted server or we have to do anything while it is build ? Assuming the hosted server will also have meteor 1.3.

Why was it necessary to do meteor run android-device ?
Should not the meteor build command take care when both the mobile platforms are already added to the app.

1 Like

As long as the ios or android platforms have been added to the project, meteor build will serve the Cordova-specific bundle. So your production server should support hot code push for mobile apps as usual.

When using meteor run during development however, people were complaining that Meteor would always build the Cordova-specific bundle, even if they were just testing in the browser. So that’s why I made this change and now only build for Cordova when a mobile target has been specified.

Cool !. That explains it all. Thank you so much !

@martijnwalraven, for me this change causes some regression.

My setup involves separate view layers for the different platforms, so it requires some customization to the apps.

I am using a custom build process for the apps, so I am relying on hot code push to update the app UIs when developing.

This change forces me to have Meteor rebuild the app (without my custom setup), uninstall the newly built app from the device and reinstall my custom built app every time I run the dev server.

Any chance of adding a CLI option to build the Cordova stuff as before?
I don’t want to have to fork the Meteor tool as well :frowning:

@alon: What change specifically is causing you trouble? Could you explain in more detail what your custom build process entails?

It is mainly overwriting some files in the cordova projects (to override some things with project configs and the web server).

I use the default websocket for my API server and create another websocket in a custom version of autoupdate to contact the UI server (the meteor server with the mobile app UI, let’s refer to it as the UI server).
At the moment, I am using a hack-ish solution to connect to the UI server (as its URL is different from the API server’s) and get the manifest and the bundle for hot code reloading.

I am also using AndroidStudio to debug the native Android stuff at runtime by attaching to the process.

I wish there also was a way to specify an optional environment variable or config for the UI server such that it would be possible to have a single API server and a separate UI server for each platform.
Do you think that implementing such a parameter is reasonable?

So what change in 1.3 is causing you trouble with this workflow? What is different?

Hot code push always uses the default DDP connection (which seems reasonable, because this is the server that serves the app code), but you could use DDP.connect to connect to another server (what you refer to as an API server) if you want. Wouldn’t that work for you?

That could work, but it would require some changes to the applications, as the collections and (mainly) method calls won’t be using the default DDP connection (so no more Meteor.call()).

That would still require a Cordova build (that takes a few minutes, IIRC, when specifying a mobile runTarget to mteeor run) every time I start the dev server.

I can live with the changes to the app code (as those are mainly search+replace with my dependency injection setup), but being able to instruct the app to build the cordova-related server resources instead of the entire mobile app when starting the dev server will save me (and others, I guess) a significant amount of time.

@martijnwalraven, do you think that you can add a CLI flag like --build-corodva-targets that will instruct the meteor tool to build those targets as before?

2 Likes