Search Unity

SubscriptionManager crashes by InvalidProductTypeException in Android device.

Discussion in 'Unity IAP' started by waken, Jan 27, 2020.

  1. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    I tried to use SubscriptionManager.
    The following is the code.

    Code (CSharp):
    1.  
    2. Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
    3.  
    4. foreach (var item in controller.products.all)
    5. {
    6.     if (item.availableToPurchase)
    7.     {
    8.         Debug.Log(string.Join(" - ",
    9.                     new[]
    10.                     {
    11.                     item.metadata.localizedTitle,
    12.                     item.transactionID,
    13.                     item.receipt
    14.                     }));
    15.         if (item.receipt != null)
    16.         {
    17.             if (item.definition.type == ProductType.Subscription)
    18.             {
    19.                 if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
    20.                     string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
    21.                     subscriptionManager = new SubscriptionManager(item, intro_json);
    22.                     SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
    23.                     Debug.Log("product id is: " + info.getProductId());
    24.  
    I referred to IAPDemo.cs.
    This code works fine in iOS device, but an exception is occurred in Android device.
    Here is the exception.

    I tried to use m_GooglePlayStoreExtensions.GetProductJSONDictionary() instead of m_AppleExtensions.GetIntroductoryPriceDictionary(), but it didn't work neither.

    Can I use SubscriptionManager in Android device?
    If so, how should I fix my code?

    Unity version is 2018.4.15f1.
    IAP version is 1.23.1.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Could you please narrow down the line where the exception occurs? And it doesn't look like you included the entire method.
     
  3. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    Here is the entire function.
    The exception occurs on the line 33, "SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();"

    Code (CSharp):
    1. public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    2. {
    3.     m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();
    4.     m_AppleExtensions.RegisterPurchaseDeferredListener(OnDeferred);
    5.  
    6.     Debug.Log("OnInitialized: PASS");
    7.  
    8.     storeController = controller;
    9.     storeExtensionProvider = extensions;
    10.  
    11.     m_GooglePlayStoreExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();
    12.  
    13.     Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
    14.  
    15.     foreach (var item in controller.products.all)
    16.     {
    17.         if (item.availableToPurchase)
    18.         {
    19.             Debug.Log(string.Join(" - ",
    20.                         new[]
    21.                         {
    22.                         item.metadata.localizedTitle,
    23.                         item.transactionID,
    24.                         item.receipt
    25.                         }));
    26.             if (item.receipt != null)
    27.             {
    28.                 if (item.definition.type == ProductType.Subscription)
    29.                 {
    30.                     if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
    31.                         string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
    32.                         subscriptionManager = new SubscriptionManager(item, intro_json);
    33.                         SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
    34.                         Debug.Log("product id is: " + info.getProductId());
    35.                         Debug.Log("purchase date is: " + info.getPurchaseDate());
    36.                         Debug.Log("subscription next billing date is: " + info.getExpireDate());
    37.                         Debug.Log("is subscribed? " + info.isSubscribed().ToString());
    38.                         Debug.Log("is expired? " + info.isExpired().ToString());
    39.                         Debug.Log("is cancelled? " + info.isCancelled());
    40.                         Debug.Log("product is in free trial peroid? " + info.isFreeTrial());
    41.                         Debug.Log("product is auto renewing? " + info.isAutoRenewing());
    42.                         Debug.Log("subscription remaining valid time until next billing date is: " + info.getRemainingTime());
    43.                         Debug.Log("is this product in introductory price period? " + info.isIntroductoryPricePeriod());
    44.                         Debug.Log("the product introductory localized price is: " + info.getIntroductoryPrice());
    45.                         Debug.Log("the product introductory price period is: " + info.getIntroductoryPricePeriod());
    46.                         Debug.Log("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles());
    47.  
    48.                         if (Result.True == info.isSubscribed())
    49.                         {
    50.                             if (Result.True == info.isCancelled())
    51.                             {
    52.                                 Debug.Log( "Subscription Canceled" );
    53.                             }
    54.                             else
    55.                             {
    56.                             }
    57.                         }
    58.                         else if (Result.True == info.isExpired())
    59.                         {
    60.                             Debug.Log( "Subscription Expired" );
    61.                         }
    62.                     }
    63.                     else {
    64.                         Debug.Log("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class.");
    65.                     }
    66.                 }
    67.                 else
    68.                 {
    69.                     Debug.Log("the product is not a subscription product");
    70.                 }
    71.             }
    72.             else
    73.             {
    74.                 Debug.Log("the product should have a valid receipt");
    75.             }
    76.         }
    77.     }
    78. }
    79.  
     
    Last edited: Jan 28, 2020
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Thanks for the additional information, we have confirmed and the fix should be included in the next release, hopefully in a few weeks.
     
    waken likes this.
  5. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    Thank you!
    I'm looking forward to the next release.
     
  6. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    We're still getting this error on V2.0.6 on Unity 2019.1.10f1. Is there an update yet? If not, is there a work around for Android subscriptions?
     
  7. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    I will ask the team about its latest status.
     
  8. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    Do you have an update about this? The fix was said to be complete 2 months ago.
     
  9. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    Thanks, @SamOYUnity3D but this is VERY critical as its technically broken for all subscriptions on Android. Is there a work-around or a repo that we can use until release?
     
  10. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    I suggest you update to the latest IAP version, and use the following code to avoid the app crash.
    Code (CSharp):
    1.         try
    2.         {
    3.             SubscriptionManager p = new SubscriptionManager(item, intro_json);
    4.             SubscriptionInfo info = p.getSubscriptionInfo();
    5.         }
    6.         catch (Exception ex)
    7.         {
    8.             Debug.Log(ex);
    9.         }
     
  11. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    Thanks @SamOYUnity3D. We're already doing that but it just avoids the crash. We have no info about the subscription status so we have to auto-assume that it's still active if it fails to parse.

    Is the plugin being deprecated? aka, we should find alternative ways of fixing this?
     
    waken likes this.
  12. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    We have addressed this issue before and it has been fixed in IAP 1.22.1 and later. Since you mentioned that you still encounter this issue in the latest IAP version, I think we need further investigation. I would appreciate it if you can provide steps to reproduce.
     
  13. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    OK sure. Let's start by making sure we have the correct versions.

    The Package manager says Version 2.0.6 which is the latest version available. The Changelog.md says
    [1.23.1] - 2019-11-18
    . If the bug has been resolved at the end of January, do we have that fix or not?
     
  14. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    I see. I think this is a new issue. We couldn't reproduce this issue in the latest version, it will be helpful if you can provide it. Also, could you attach the device log here for investigation? Thanks.
     
    JeffDUnity3D likes this.
  15. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    Logs attached. Look for 'Failed reading subscription info'.
     

    Attached Files:

    waken likes this.
  16. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, it does indeed look like the same issue that we fixed, and no longer reproduced for us as the time. What product type is this receipt for? Are you checking to make sure it's a Subscription receipt first?
     
  17. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    Agreed with Jeff. I can reproduce this issue if I don't use 'if (item.definition.type == ProductType.Subscription)' to check whether the product is a subscription product.

    Code (CSharp):
    1. public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    2. {
    3.     m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();
    4.     storeController = controller;
    5.     storeExtensionProvider = extensions;
    6.  
    7.     m_GooglePlayStoreExtensions = extensions.GetExtension<IGooglePlayStoreExtensions>();
    8.  
    9.     Dictionary<string, string> introductory_info_dict = m_AppleExtensions.GetIntroductoryPriceDictionary();
    10.  
    11.     foreach (var item in controller.products.all)
    12.     {
    13.         if (item.availableToPurchase)
    14.         {
    15.             if (item.receipt != null)
    16.             {
    17.                 if (item.definition.type == ProductType.Subscription)//Please use this to make sure it's a subscription receipt first.
    18.                 {
    19.                     if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
    20.                         string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
    21.                         subscriptionManager = new SubscriptionManager(item, intro_json);
    22.                         SubscriptionInfo info = subscriptionManager.getSubscriptionInfo();
    23.                     }
    24.                     else {
    25.  
    26.                     }
    27.                 }
    28.                 else
    29.                 {
    30.                     Debug.Log("the product is not a subscription product");
    31.                 }
    32.             }
    33.             else
    34.             {
    35.                 Debug.Log("the product should have a valid receipt");
    36.             }
    37.         }
    38.     }
    39. }
    upload_2020-4-14_15-24-48.png
     
  18. AnthonyFSG

    AnthonyFSG

    Joined:
    Feb 3, 2018
    Posts:
    7
    Thank you both. We are doing that check already (as you can see from the snippet below).

    Code (CSharp):
    1.  
    2.       [SIZE=4]  foreach (Product product in _storeController.products.all)
    3.         {
    4.             Debug.LogFormat("Product: {0}. HasReceipt: {1}. Type: {2}.", product.definition.id, product.hasReceipt, product.definition.type);
    5.             if (product.definition.type == ProductType.Subscription)
    6.             {
    7.                 if (!string.IsNullOrEmpty(product.receipt) && IsAValidSubscription(product.receipt))
    8.                 {
    9.                     SubscriptionManager p = new SubscriptionManager(product, string.Empty);
    10.                     try
    11.                     {
    12.                         SubscriptionInfo info = p.getSubscriptionInfo();
    13.                         Debug.Log("Subscription. product id is: " + info.getProductId());
    14.                     }
    15.                     catch (Exception e)
    16.                     {
    17.                         Debug.LogErrorFormat("Failed reading subscription info. Error: {0}", e);
    18.                     }
    19.                 }
    20.             }
    21.         }[/SIZE]
    22.  
     
    waken likes this.
  19. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide the device logs that confirms. They will contain the Debug.Log information. Does this happen for all your subscriptions, and all your users? Your test users need to download the game via Google Play, AFTER opting into the test program from a browser on the device.
     
  20. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    I am still waiting for this issue to be resolved.

    Here is the log.

    As I mentioned before,

    Unity version is 2018.4.15f1.
    IAP version is 1.23.1.

    Do I have to update Unity version?

    I have uploaded my apk to Google Play as internal testing, then download it and test it.
     
  21. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    Could you attach the full device log? You don't need to update the Unity version.
     
  22. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    I attached the log file.
    I tried to update the Unity to version 2019.3.9f1, but the problem still happens.
     

    Attached Files:

    • log.txt
      File size:
      369 KB
      Views:
      434
  23. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    Thank you for your information. It seems that the order ID "GPA.3316-1597-2493-50425" has this issue. Could you provide a screenshot of the order ID "GPA.3316-1597-2493-50425" like below for further investigation?
    upload_2020-5-7_11-48-42.png
     
  24. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    Thank you for your reply.
    Here is the screenshot.

    Screenshot 2020-05-07 18.16.22.png
     
  25. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    Please note that the order type is "In App Product" instead of "Subscription", which means that the type of this product is consumable or non-consumable, not a subscription product.
     
  26. waken

    waken

    Joined:
    Apr 20, 2015
    Posts:
    7
    Thank you very for your answer.
    I didn't notice that. Now it seems to work fine.
    Thank you.
     
    SamOYUnity3D likes this.