Google Play Services do not work since CoronaSDK 2016.3005

After upgrading Corona SDK  from public release to 3005 we have a error when calling gameNetwork functions:

12-14 19:07:24.731: E/AndroidRuntime(2853): java.lang.IllegalStateException: The meta-data tag in your app's AndroidManifest.xml does not have the right value. &nbsp;Expected 4242000 but found 9683000. &nbsp;You must have the following declaration within the \<application\> element: &nbsp; &nbsp; \<meta-data android:name="com.google.android.gms.version" android:value="@integer/google\_play\_services\_version" /\>12-14 19:07:24.731: E/AndroidRuntime(2853): at com.google.android.gms.common.GooglePlayServicesUtil.n(Unknown Source) 12-14 19:07:24.731: E/AndroidRuntime(2853): at com.google.android.gms.common.GooglePlayServicesUtil.isGooglePlayServicesAvailable(Unknown Source) 12-14 19:07:24.731: E/AndroidRuntime(2853): at CoronaProvider.gameNetwork.google.GameHelper.beginUserInitiatedSignIn(GameHelper.java:348) 12-14 19:07:24.731: E/AndroidRuntime(2853): at CoronaProvider.gameNetwork.google.LuaLoader$3.run(LuaLoader.java:192) 12-14 19:07:24.731: E/AndroidRuntime(2853): at android.os.Handler.handleCallback(Handler.java:739) 12-14 19:07:24.731: E/AndroidRuntime(2853): at android.os.Handler.dispatchMessage(Handler.java:95) 12-14 19:07:24.731: E/AndroidRuntime(2853): at android.os.Looper.loop(Looper.java:148) 12-14 19:07:24.731: E/AndroidRuntime(2853): at android.app.ActivityThread.main(ActivityThread.java:7325) 12-14 19:07:24.731: E/AndroidRuntime(2853): at java.lang.reflect.Method.invoke(Native Method) 12-14 19:07:24.731: E/AndroidRuntime(2853): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 12-14 19:07:24.731: E/AndroidRuntime(2853): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

build settings plugins section:

plugins = {&nbsp; &nbsp; &nbsp; &nbsp; ["CoronaProvider.analytics.flurry"] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supportedPlatforms = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iphone = true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android = true, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ["iphone-sim"] = true &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; ["plugin.google.play.services"] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supportedPlatforms = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iphone = true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android = true, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ["iphone-sim"] = true &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; -- Используется для GameCenter &nbsp; &nbsp; &nbsp; &nbsp; ["CoronaProvider.gameNetwork.apple"] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supportedPlatforms = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iphone = true, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ["iphone-sim"] = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; ["CoronaProvider.gameNetwork.google"] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supportedPlatforms = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; ["plugin.notifications"] = &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs" &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; ["plugin.google.iap.v3"] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = "com.coronalabs", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supportedPlatforms = { android = true } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; ['plugin.vk'] = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; publisherId = 'com.spiralcodestudio' &nbsp; &nbsp; &nbsp; &nbsp; }

I’ve asked an engineer to look into this. 

Rob

Starting with build 3005, we’ve enabled our new plugin dependency system. In doing so and plugin we had labled as “Legacy”, is not compatible with the new dependency system. You have two choices, continue to use the old GameNetwork implementation of GPGS and use build prior to 3005 or update your GPGS to the new plugin (recommended). 

Rob

Would eventually be nice to get some proper documention for the new GPGS if we’re basically being forced to use it!

The documentation for the new Google Play Game Services plugin can be found here: https://docs.coronalabs.com/plugin/gpgs/index.html.

We’ve made the plugin backward-compatible with the legacy gameNetwork-google to ease the migration process, but I can see how the lack of example code makes this feel “improper”.

Regarding “legacy” plugins, if a plugin is marked as “legacy” in our docs, it effectively means that the plugin is deprecated. This usually means that we will not continue to support said “legacy” plugin with updates, leaving it vulnerable to be non-functional at any time (with or without notice). The introduction of Android plugin dependencies just happened to be a case where this plugin ended up breaking as a result.

Understand that writing and re-writing and re-writing software is just a part of the development process and that can introduce breaking changes between versions. Every company that provides SDKs of some kind is guilty of this. This is why we’re now at version 4 of Facebook support, version 3 of Google In-App Purchase support, version 2 of Amazon In-App Purchase support, etc.

Hello Ajay;

I’m looking forward to working with the new GPGS plugin. I’m excited about all of the new things it can do. At the moment, I am having to update a number of apps to work with the Professional Bundle (hence, forced removal of older Game Services plugin) and all of these games have very robust, very reliable implementations of Google Play reporting high scores, tracking achievements, etcetera.

All of this leads to my question regarding “backward-compatibility”. In the writeup about the new GPGS plugin (and in your comments), “backward-compatible” is stressed. To me, that would mean that older code and calls are supported and would not need to be rewritten. As an example, these are typical calls to the old plugin:

[lua]

gameNetwork.request(“loadLocalPlayer”,  {listener=mygpgslistener})

gameNetwork.request(“setHighScore”,  {localPlayerScore = {category = “example”, value=100}, listener=mygpgslistener})

gameNetwork.request(“unlockAchievement”,  { achievement = { identifier = “example” }, listener=mygpgslistener})

[/lua]

In looking through the documentation, I do see certain parallel call for most of the previous ones but no parallel call for "loadLocalPlayer” (and maybe some others). Could you comment and clarify on this? 

And when there is a parallel call (essentially the same call from old plugin to new), can we expect the returned data (tables) to contain essentially the same data with the same variable names and same data structure? Or is this going to have to be tested carefully with each and every instance of a call?

Thanks. I will greatly appreciate clarification.

Steve 

Hi Ajay (and Ingemar of Corona);

As a followup to my Saturday Post (immediately above), I was just reading a forum post by Ingemar_cl (Corona Staff - post was last Wednesday) where he addressed a question from Rune7 similar to my question. Rune7 also has games that contain Google Leaderboards, etc. and need to be updated for Pro plugins.

Rune7 asked about the steps to move from the old plugin to the new GPGS and this is what Ingemar_cl said:

“CoronaProvider.gameNetwork.google is replaced with plugin.gpgs and is fully backwards compatible so it should just be a matter of changing the plugin specification in build.settings, and the ‘require’ statement in your Lua files.
 
CoronaProvider.analytics.flurry is replaced with plugin.flurry.analytics. The logEvent() statements are fully backwards compatible. You’ll only need to change one line for init() as it accepts a listener now.
 
By doing that you should be “future proof” as these plugins are maintained. Also the new plugins have additional functionality should you decide to expand your app to use them.”

So is this true? Does the older syntax and do the older calls work without modification? Would love to get some guidance on this as soon as practical.

Thank you;

Steve

If you look here: https://coronalabs.com/blog/2016/09/02/our-new-google-play-games-services-gpgs-plugin-is-available/

It says: “IMPORTANT — If you want to upgrade to this new plugin, you should remove the legacy plugin from build.settings, if you’ve included it. Although this new plugin is fully backward-compatible with the legacy API calls, you can not include both plugins inside your build.settings file.”

Rob

Yes Rob. 

Cmon Rob. OF COURSE I SAW THAT. I’m not a beginner.

I changed out the plugin entirely, did the new “require” and built the app for Google Play/Android last week. But the very first time I ran the app on a device, as soon as the app did a “gameNetwork.request” (the old syntax is built around “requests”), the device threw an error that said “request” was not one of the functions (a syntax error). I think the request was “loadLocalPlayer”. As that was last Thursday, I don’t have the exact syntax.

So . . . that is why I was asking for confirmation that the old syntax still works and returns the same data (which is what “backward compatibility” is all about). So can you or Ajay or Ingemar actually confirm that a “request” (old syntax) will work?

Steve

sbullock, how do you require the new plugin? To keep the old syntax it should be

local gameNetwork = require("plugin.gpgs")

Also, the corresponding call for the loadLocalPlayer request is gpgs.players.load() without playerId or playerIds params.

Hi Lerg;

Thanks for the clarity of your reply. 

If I might extend your point (and tell me if I am wrong), what you are saying is that there are “generally equivalent” (but syntactically completely different) calls in the new GPGS plugin (when compared with the old) that generally accomplish the same things.

And in terms of what those calls return from Google (so they can be parsed and dealt with), we developers will need to test and carefully compare the new returned data against the old returned data.  Is this correct???

If this is, indeed, the case, then this developer strongly believes that Corona needs to TOTALLY REMOVE the words “backward compatible” from your docs and from posts like Rob’s and Ingemar’s that are shown above. (“all you have to do is change build.settings and the require”)

Yes, the new plugin does everything the old one did and so much more – that description of the newer plugin is quite valid.

When Windows 10 and every other version of Windows came out, “backward combatibility” meant that developers who created programs to run on older versions such as Vista (or even Windows XP) did not need to go back and change every single call to the OS in order to have their programs now work with Windows 10.  

But it seems to be the case with the new GPGS plugin where every legacy call will need to be changed. Do correct me if I am wrong.

If we will need to take EVERY legacy call addressing Google Play and change it (note: some are “similar” but actually different if you burrow into the docs), and if we need to take every batch of data returned by Google and examine it for differences with the old plugin’s returned data . . . I can handle this and so can your other skilled developers. Just, please, don’t throw out the illusion that this is “backward compatibility”.

That term implies that it will take minutes to make the change (or no time at all if it was Microsoft-like “compatibility”).

For someone who is doing a lot with various achievements and high scores in legacy code (over a number of apps), the change to the new plugin and testing for robust reliability on each app will be measured in days rather than minutes. As I said, it’s my job to do this stuff and handle these changes; so I will. I simply dislike misleading descriptors. :slight_smile:

Steve

P.S. In my 23+ years of programming and game development, I think this is the first time I have ever held up Microsoft as an example of correct practices. Jeesh!

sbullock, yes, you are wrong and your concept of backward compatibility is correct. Generally it takes only build.settings and require to change to use the new plugin and keep the legacy syntax.

Hi Lerg;

Now you have me completely confused. You are saying that these sort of legacy calls will NOT NEED TO BE CHANGED (and the Google returns from the new calls won’t need to be examined for changes or differing variable names or anything)?? Is that correct? I had asked about these sorts of calls in my initial post and never got an answer.

  1.  
  2. gameNetwork.request(“setHighScore”,  {localPlayerScore = {category = “example”, value=100}, listener=mygpgslistener})
  3. gameNetwork.request(“unlockAchievement”,  { achievement = { identifier = “example” }, listener=mygpgslistener})

Thanks.

 

Steve

sbullock, sorry for the confusion, but as we all said earlier you don’t need to change your code. It should work just fine.
Also they are not HTTP requests, the plugin has full control over what form is used to return data.

If the new plugin is not working in legacy mode as expected, then it’s a bug. Given that it’s properly set up.

Thanks Lerg;

Got it now. The only legacy code I DO NEED TO CHANGE is the “loadLocalPlayer” because you said

“the corresponding call for the loadLocalPlayer request is gpgs.players.load()  without  playerId or playerIds params.”

None of the rest of the legacy calls need to be changed. Appreciate the assistance.

Steve

Corresponding in the new syntax. Old syntax should also work. I am sure I did test it.

I’ve asked an engineer to look into this. 

Rob

Starting with build 3005, we’ve enabled our new plugin dependency system. In doing so and plugin we had labled as “Legacy”, is not compatible with the new dependency system. You have two choices, continue to use the old GameNetwork implementation of GPGS and use build prior to 3005 or update your GPGS to the new plugin (recommended). 

Rob

Would eventually be nice to get some proper documention for the new GPGS if we’re basically being forced to use it!

The documentation for the new Google Play Game Services plugin can be found here: https://docs.coronalabs.com/plugin/gpgs/index.html.

We’ve made the plugin backward-compatible with the legacy gameNetwork-google to ease the migration process, but I can see how the lack of example code makes this feel “improper”.

Regarding “legacy” plugins, if a plugin is marked as “legacy” in our docs, it effectively means that the plugin is deprecated. This usually means that we will not continue to support said “legacy” plugin with updates, leaving it vulnerable to be non-functional at any time (with or without notice). The introduction of Android plugin dependencies just happened to be a case where this plugin ended up breaking as a result.

Understand that writing and re-writing and re-writing software is just a part of the development process and that can introduce breaking changes between versions. Every company that provides SDKs of some kind is guilty of this. This is why we’re now at version 4 of Facebook support, version 3 of Google In-App Purchase support, version 2 of Amazon In-App Purchase support, etc.