Meteor Android App - Google Map

Hi All,

Need some pointers to debug. I have an Android Meteor App and it uses Google Maps to show location. It has been happily working for last couple of years, but suddenly it stopped working from yesterday, however the same app opened on browser loads Google Maps. Any hints to solve this…Thanks

Google Maps is really a large bunch of products. I take it Android Meteor App = Cordova in which case you would normally use an API (Maps Javascript API). This is a paid service with a limited free bundle.
It may stop working when a cost is registered but there is a cap, when an API key was generated before a credit card was mandatory to register, sometimes keys just stop working and a new key needs to be generated (this is why it is better to provide this key to the user in a dynamic way which allows a change without even HCP.

I think you could also use an Map Embed API which still requires a key but it is a free service. In this case … maybe something wrong with the key.

It is common that people who write here give very very very little information and leave it to the imagination of others to come with interesting stories that might help.

You might be using a Goole Maps API key which has been generated in Google Cloud Console (https://console.cloud.google.com/). In the console you may find errors and understand where they come from and why.

Thanks @paulishca

Actually found the error after some debugging. I use dburles:google-maps. It is hardcoded to use api version 3.x but it looks like if google does not find matching version number, it defaults to the latest.

There are some breaking changes in the latest api 3.54 and 3.53, that break the webview used within the android app. Changing it to 3.52 solved it. But it is going to go end of life soon(another couple of months), hopefully updated webview or google api will fix the problem.

We’ve had the same problem with google-map-react and we just added a props to specify the version v: “3.52” . Please note it only worked with an older version of this npm.

Thanks a lot @perumalkuk for giving your solution!

How did you find that the version was the problem ? We have not seen anything in the logs.

Regards,

Burni

I will admit it was not easy. It was more of doing elimination.

First new debugging Cordova app has become tougher, the Chrome Inspect developer options no longer worker as it used to be.

And to make ‘meteor run android’ or ‘meteor run android-device’ is not easy as it seems the cmdline tools (new) may get installed in different folder than usual and one has to specifically set the path to point to the bin folder for the avd manager to work, along with this the gradle, kotlin and java version need to be correct. (I understand with 34 we need to bump gradle and Java…not sure how things will be)

Coming back to debugging, once I was able to make ‘meteor run android-device’ work. The output cleared showed the issue was the initialise phase Google Maps API (as I said I use dburles:Google-map package) . It was returning 2 types of errors depending on parameters passed ‘jv.entries not iterable’ or ‘cfa.entries not iterable’ but the difficult thing was it was working on normal web browser.

On looking at the output of API init, the functions for looping on jv and cfa were indeed defined. So my first thought was I was not passing something valid to the init call for Google maps. The three things it was using was – key, version and libraries . Key was ruled out as it was working on browser, removing libraries did not have much impact --so it was something to do with version.
And ‘3.x’ was being passed to the version - even tough it looked odd, it used to work and it was working with browser.
After lot of googling I noticed the google fine print …from google

Release channels and version numbers

In your application you can specify release channels or version numbers:

  • The weekly channel is specified with v=weekly.
    This channel is updated once per week, and is the most current.
  • The quarterly channel is specified with v=quarterly.
    This channel is updated once per quarter, and is the most predictable.
  • The beta channel is specified with v=beta.
    This channel is based on the weekly channel, and is updated once per week. It includes additional changes for early testing and feedback.
  • The alpha channel is specified with v=alpha.
    This channel is based on the beta channel, and is updated once per week. It includes experiments for customer feedback on prototypes. It is for development purposes only and should not be used in production.
  • The version number is specified with v=n.nn.
    You can choose v=3.54, v=3.53, v=3.52 or v=3.51.
    Version numbers are updated once per quarter (see Quarterly updates)

If you do not explicitly specify a channel or version, you will receive the weekly channel by default…

The details is in the fine print. It seemed that I was getting the latest version API version by default. With this information I started iterating with each version …and found 3.52 worked…

Sorry about the long post

Hi @perumalkuk,

Thanks a LOT for the detailed answer. We did not manage to find any error message anywhere. We’ve tried with adb logcat without seeing anything helpful.

Your post here yesterday really allowed us to fix it as well.

Thank you so much!

Regards,
Burni

Glad to be of help.

Have you noticed that adb is now not showing console messages. Looks like the production build suppresses the console output. This is why it took some time to find the actual error.

So, it looks like any version of the Google Maps javascript library after 3.53 will cause the maps not to load. Version 3.53 will be sunsetted in May 2024 and will not be available. Is there a way to make meteor compatible with later versions of the maps library (or, in other words support ecmascript 2020)?

I’m currently working on that, will report back

1 Like

Great! Anything I can do to help? I tried updating to Meteor 2.14 and just used a meteor minimal app and, if the code is transpiled by meteor, code like this works:

$ca = new Map([[1, ["msie"]], [2, ["edge"]], [3, ["chrome", "crios"]], [5, ["firefox", "fxios"]], [4, ["applewebkit"]], [6, ["trident"]], [7, ["mozilla"]]]);
for (const [d,e] of $ca.entries()) { console.log(d + "=" +  e); }

But if I run the minimal app in an android studio virtual device, connect via chrome dev tools and type the same code in to the console, I get:

VM58:2 Uncaught TypeError: $ca.entries is not a function or its return value is not iterable
    at <anonymous>:2:25

I’m not sure why the Android Webview is not supporting ES2020. Maybe Meteor 3.0? I also thought maybe I could use babel-standalone and process the google maps js on the client, but had no success with that and that seems reather clunky. Is some meteor package overriding the native functionality of Map?

I think there is much inconsistency within the Cordova inner browser (webview) world.
I don’t know if Cordova build respects the settings of modern browser package (‘meteor/modern-browsers’). On the device you test you may try to identify the version of your inner browser and make sure your Maps are supported by that version. You can set that version outside the modern browser range and hope to have it compiled to ES5.

As I understand, even if it works on one Android phone … it might not work on another due to the use of different versions and different vendors even by different mobile phones.
I think in Cordova, since you pack the app for an upfront download it is good to compile everything for ES5.

The problem with google maps is that it is loaded at runtime via script tag injection. I’ve tried to use Babel at runtime to convert the dynamically loaded google maps js, but get the following error.

TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
    at _nonIterableSpread (babel.js:604:11)
    at _toConsumableArray (babel.js:579:100)
    at _callee2$ (config-chain.ts:724:43)
    at tryCatch (babel.js:127:18)
    at Generator.<anonymous> (babel.js:215:19)
    at Generator.next (babel.js:156:23)
    at tryCatch (babel.js:127:18)

I’ve tried loading different plugins into Babel at runtime and I always get the same error above. The babel used at compile time when building my app correctly transpiles the code, but not at runtime. I feel like some package within Meteor or a third party package is overriding some expected implemetation required by Babel.

I guess you can just build your own package with a working compiled version of Google Maps.

Has anybody been successful at making it work ?

@tdub7229 ? @ralof ?

I couldn’t come up with a successful solution. You might want to investigate leafletjs with openMaps. Depending on your map needs, it can be free, or you can use some of the custom tiled maps that companies have developed. They also have a map marker clustering library which was a feature of google maps that I needed. With leaflet, you don’t have to depend on downloading any source code when you run your app; you can just statically embed it in your product. (You still need an active connection to get the map tiles though). I’ve been very happy with it.
I don’t think a lot of people are aware that the google maps version retirement in May 2024 is going to be breaking their apps.

When I was trying to fix the issue I noticed the application was working perfectly fine on chrome. So I think it is probably issue is with the webview in Cordova

@perumalkuk yeah. We noticed the same thing. That’s quite weird. I wonder what the difference is between Chrome and the Webview. And it’s on both Android and iOS so it’s most probably something common between the two.

Could it be the build rules ?

Experiment: Could you please try to get the API from version 3.53.13? Maps JavaScript API Release Notes  |  Google for Developers

Documentation for versioning: Versioning  |  Maps JavaScript API  |  Google for Developers

Then with something like this: Yarn let’s try to get some details of the WebView/Browser and try to understand whether the WebView version is recent, old and if it can be brought up to date etc…