plugin.google.iap.v3 not working in Build 3160

Hi, the Google Play plugin works perfectly and downloads store products as it should when built with build 3068, but not with any of the builds since 3135. The store property “isActive” is always false and the communication process does not go beyond transaction state = initialized.

Can anyone help me with this?

Regards,

Rob

store = {

canLoadProducts = true,

canMakePurchases = true,

canPurchaseSubscriptions = true,

consumePurchase = <function 1>,

finishTransaction = <function 2>,

init = <function 3>,

isActive = false,

loadProducts = <function 4>,

purchase = <function 5>,

purchaseSubscription = <function 6>,

restore = <function 7>,

target = “google”

}

Perhaps you’re running into this:

https://coronalabs.com/blog/2017/07/19/important-google-iap-plugin-update/

Rob

I was having similar issues after not having updated my app for several months with the new SDK.   Calling store.LoadProducts after init was causing a runtime error of “java.lang.RuntimeException: java.lang.IllegalStateException: IAB helper is not set up. Can’t perform operation: queryInventory” and crashing the game.  

Hopefully searches for this issue and error will lead to the solution here.

We had to make a change to how the Google IAP plugin was being initialized because it was causing an excessive number of ANR (App Not Responding) errors on Android devices.

Calling store.init() returns immediately.  If you do things like call loadProducts() immediately afterwards, init() won’t be finished and things will break. You can either a) defer things until you really need them. I doubt many apps really need to load IAP products in the first couple of frames of execution, or wait on the .init()'s call back function to get triggered with a state that says the initialization is complete.

Rob

Yup I got it working now, thanks.  The bulk of my time this morning was looking for what was causing the problem.   

Yep, that was it. Thanks Rob, I’ve got it working now. However, now the plugin works slightly differently to the iOS and Amazon plugins making the code a little less elegant for true cross platform development, which is OK, as long as it works, but it raises the question, are there any plans to change the iOS and Amazon plugins to match the functionality of the Google Play plugin? Just wondering if I need to keep an eye out for upcoming changes.

It would be nice if they all behaved the same.  I get around it by deferring things until I actually need them. I don’t need to loadProducts until someone goes to my store scene. My restore is on a user button.

But if I’m being honest, updating iOS and Amazon are not high on the list for this particular feature.

Rob

Does anyone have a working example of a correct restore procedure? I read the blog post (https://coronalabs.com/blog/2017/07/19/important-google-iap-plugin-update/) and the new documentary (https://docs.coronalabs.com/plugin/google-iap-v3/init.html) with the sample code, but still don’t understand where exactly do I call store.restore() safely …

Thanks a lot!

I would recommend putting a button in your app’s interface that lets the user choose when to restore.  

Rob

OK, but I still have to find out how to implement the restore procedure (with or without button) correctly… and haven’t seen a working example of how to implement it with this new asynchronous Google IAP.

One of my apps is not usuable right now, it produces that “IAP Error: IAB helper is not set up” error. My older apps are working fine, but I cannot make any updates until I figure out how to do this correctly.

It’s right here:

https://docs.coronalabs.com/plugin/google-iap-v3/init.html

It shows how to test for the “init” event in the transaction listener and has a note:

" – Perform steps to enable IAP, load products, etc."

You can put store.restore() there on Android as you will know for certain that IAP is initialized at that point. This is only for Google.  Amazon and iOS do not generate this event.  However, for iOS and Amazon, when store.init() completes, the initialization process is complete and you can safely call store.restore(), store.loadProducts() etc.

That said and let me re-state. If you’re only focused on Amazon, it’s okay to call store.restore() when you get that iniit event. However, if you have any plans on supporting iOS (and macOS, tvOS as well). You will 100% get rejected if there isn’t a button in the user interface that calls store.restore().  If you put restore on a button in a rational place for it and you’ve called store.init() and do nothing else, it should work.  Store.init() should be well complete before a human can press a restore purchases button.

store.restore()'s sole purpose is to restore purchases if the user deletes the app and re-installs it. It’s not designed as a tool for you to use to unlock things as a convenience.  You should track the things that the user unlocked independently and not depend on store.restore() to unlock the app every time the user runs it. I don’t know if that’s what you’re trying to do. I know others have gone that route instead of maintaining their own unlocked items.

Rob

Thanks Rob for the clarification, I really appreciate this. Yes, I do track the already unlocked app. But in the past, I still had an additional automatic restore on the start of the app, so this will now be placed on the button (like I already had done for iOS).

Perhaps you’re running into this:

https://coronalabs.com/blog/2017/07/19/important-google-iap-plugin-update/

Rob

I was having similar issues after not having updated my app for several months with the new SDK.   Calling store.LoadProducts after init was causing a runtime error of “java.lang.RuntimeException: java.lang.IllegalStateException: IAB helper is not set up. Can’t perform operation: queryInventory” and crashing the game.  

Hopefully searches for this issue and error will lead to the solution here.

We had to make a change to how the Google IAP plugin was being initialized because it was causing an excessive number of ANR (App Not Responding) errors on Android devices.

Calling store.init() returns immediately.  If you do things like call loadProducts() immediately afterwards, init() won’t be finished and things will break. You can either a) defer things until you really need them. I doubt many apps really need to load IAP products in the first couple of frames of execution, or wait on the .init()'s call back function to get triggered with a state that says the initialization is complete.

Rob

Yup I got it working now, thanks.  The bulk of my time this morning was looking for what was causing the problem.   

Yep, that was it. Thanks Rob, I’ve got it working now. However, now the plugin works slightly differently to the iOS and Amazon plugins making the code a little less elegant for true cross platform development, which is OK, as long as it works, but it raises the question, are there any plans to change the iOS and Amazon plugins to match the functionality of the Google Play plugin? Just wondering if I need to keep an eye out for upcoming changes.

It would be nice if they all behaved the same.  I get around it by deferring things until I actually need them. I don’t need to loadProducts until someone goes to my store scene. My restore is on a user button.

But if I’m being honest, updating iOS and Amazon are not high on the list for this particular feature.

Rob

Does anyone have a working example of a correct restore procedure? I read the blog post (https://coronalabs.com/blog/2017/07/19/important-google-iap-plugin-update/) and the new documentary (https://docs.coronalabs.com/plugin/google-iap-v3/init.html) with the sample code, but still don’t understand where exactly do I call store.restore() safely …

Thanks a lot!

I would recommend putting a button in your app’s interface that lets the user choose when to restore.  

Rob