Search Unity

Bug IAP init failure creates multiple listeners and event calls

Discussion in 'Unity IAP' started by tessellation, Jan 12, 2023.

  1. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    1. Set up a Google Play Store device where no Google Account is logged in.
    2. Run Unity IAP app and you'll get an error during initialize: InitializationFailureReason.PurchasingUnavailable
    3. When this happens we notify the user with a massage saying that they need to log in with the Google Play Store app to use these features.
    4. Later, in the case when the user attempts to make a purchase in the game and in order to recover from failure (presuming they do log in to Google Play) we then re-attempt UnityPurchasing.Initialize() again. If the user does log in, then this will succeed, otherwise, we get another OnInitializeFailed event.
    5. However a bug occurs where whenever you call UnityPurchasing.Initialize() with the same
    IStoreListener object, you then start getting multiple events. For example if another PurchasingUnavailable comes in then you get two events instead of one. There's no API to remove a listener and it doesn't appear that UnityPurchasing.Initialize() does any removal of duplicate listeners. There's also no way to initialize the SDK without adding a listener.
     
  2. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
    Hello @tessellation.
    To help you find a solution to your issue we would need to know which version of IAPSDK you are running :)
     
  3. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Of course, how silly of me. We're using the latest version of the package, 4.5.2, building with Unity 2020.3.43f1 LTS. But honestly I suspect this bug has been in existence since early days of Unity IAP. We just never tested this scenario until recently. We got a new phone where no user account is connect.
     
  4. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
    No worries, thank you for your feedback @tessellation.

    We will reproduce your steps, and create a bugfix for a future release if needed.
    In the meantime, if it is a blocker for your project, you could try to create a new IStoreListener object whenever you are calling UnityPurchasing.Initialize() and only listen to the latest IStoreListener to prevent your multiple event problem.
     
  5. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Thanks for looking into it. I also submitted it as a bug through the reporting tool. Thanks for the work-around suggestion. This would create a slow memory leak if the error continues to happen. It would create paralyzed listener instances that would build-up over time but it's probably OK until the fix is available.
     
  6. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Another issue that might happen is that once IAP is initialized correctly, there will be multiple IStoreListeners and so what happens in the scenario when it calls ProcessPurchase multiple times and there's a "dead" IStoreListener and a working one? What should the dead one return? It can't return PurchaseProcessingResult.Complete because it should just ignore the callback. Is PurchaseProcessingResult.Pending the right thing to return because the working store listener will eventually likely return PurchaseProcessingResult.Complete? This also assumes the dead store listener ProcessPurchase is called before the working one.
     
    Last edited: Jan 25, 2023
  7. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
  8. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Sorry I guess I'm not following you within the context of this thread. UnityPurchasing.Initialize will recover from what? Being called multiple times? Or do you mean if we return PurchaseProcessingResult.Pending then eventually, down the road, ProcessPurchase event will be called again? Appreciate clarification on what you mean by "recover."
     
  9. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
    Thanks for your feedback.

    Sorry i wasn't clear enough, developers shouldn't have to call UnityPurchasing.Initialize multiple times.
    For exemple if it was called with no internet connection, it will retry to init until success.

    "Initialization will only fail if Unity IAP encounters an unrecoverable problem such as a misconfiguration or IAP being disabled in device settings."

    We will test your issue and let you updated.
     
    Arnaud_Gorain likes this.
  10. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Yes, I'm aware it will retry indefinitely if it's in airplane mode or no internet, but if the user hasn't logged into Google Play Store or has logged-out, then it will fail immediately with OnInitializeFailed event. I realize this is an unusual situation for most users. In this case we tell the user that they need to go to Google Play Store and log-in. So once they come back to the app, the way to recover from this failure without asking the user to restart the app is just to attempt UnityIAP initialization again. I'm sure you can come up with a better solution in the SDK because I imagine most developers don't call Initialize again and they just assume IAP isn't available for the duration of the app session.

    Thanks for the excellent support!
     
    Arnaud_Gorain likes this.
  11. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Some additional problems we found after more testing... (@aVerrecchia perhaps you can pass this along to the team because this new problem is not part of my original bug report):

    Take the above case when the user account has not been logged into Google Play Store and we get an OnInitializeFailed() event with InitializationFailureReason.PurchasingUnavailable. We've only initialized Unity IAP one time, but the event is actually fired twice. If the user then leaves the app and returns, we then immediately see 4 calls to our OnInitiailizeFailed() event. If you leave the app and return again, 6 calls. It just keeps building up! Again, Unity IAP has only been initialized once with one listener.

    This is slightly different case from what I was describing in the original post, so it represents an additional bug where multiple events are being fired from Unity IAP when there should be only one.
     
  12. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
    Thank for your feedback @tessellation, to be clear, this bug only happens if you open the app without being connected to the Play Store ?

    We will definitely include this case in our testing / fixing of IAP without a phone not connected to Google.
     
  13. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Sure happy to clarify. The phone has Google Play Store and Google Play Services installed. However, there is no account logged in:
    device-2023-02-09-180823.png
     
    aVerrecchia likes this.
  14. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    FYI for those reading this, Unity IAP v4.6.0 does solve our problem but by fixing the original issue that caused us to call UnityPurchasing.Initialize() multiple times. Our approach is now to call UnityPurchasing.Initialize() only once. After Unity IAP fails with IStoreListener.OnInitializeFailed() and then later the user adds a Google account and returns to the app, UnityIAP will now initialize automatically and call IStoreListener.OnInitialized(). Therefore, no work-around is needed to make Unity IAP operate correctly again. If you do call UnityPurchasing.Initialize() multiple time, there's still an issue where multiple callbacks will build up. If your first call to Initialize fails, your subsequent ones with not return a callback until it's able to initialize at which point you'll get multiple OnInitialized() callbacks.
     
    Last edited: Mar 23, 2023
    PeachyPixels likes this.
  15. aVerrecchia

    aVerrecchia

    Unity Technologies

    Joined:
    Jun 28, 2022
    Posts:
    34
    @tessellation Thanks for your feedback ! Just to be clear, are you on IAP 4.6.0 or 2.6.0 (which is fairly outdated and will come with it's own set of issues) ?

    UnityPurchasing.Initialize() is meant to only be called one time, It is normal that you you get multiple callbacks if you call UnityPurchasing.Initialize() multiple times.

    FYI we are currently testing the "no google account issue" with the recommended workflow of IAP.
     
  16. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Sorry you are correct, I meant 4.6.0 and we've since upgraded to 4.7.0. I'll correct the previous post.

    And yes, with that new version we're now able to call Initialize just once and IAP recovers correctly once the user logs in so we don't have to call Initialize() again.
     
    LaurieMcC likes this.