Solved

Randomly and false-zero-Entitlements returned from purchaseProduct:withCompletion

  • 22 October 2021
  • 69 replies
  • 926 views

Userlevel 3
Badge +8

Hi @taquitos  With the latest 4.0.0-Beta.3, the return from purchaseProduct:withCompletion can have zero entitlement even though it is not true.

I can’t reproduce while in debug mode (randomly happens outside the debugger).

Attached is a txt file with a log of successful return (I see some errors but not sure how to cancel them).

Thanks,

 

icon

Best answer by Andy 14 January 2022, 19:45

View original

69 replies

Took a little longer than expected, but here’s a new release: https://github.com/RevenueCat/purchases-ios/releases/tag/4.0.0-beta.6

We now add a lot more info to the error objects that get surfaced through the API.

Userlevel 3
Badge +8

@taquitos Sounds great, I am building now and hopefully release asap.

Userlevel 3
Badge +8

@taquitos here is the latest error attached from the same user, kind enough to keep posting us, with the latest beta.6

Today, I open the app on my device and I got no in-app at all and here is my log (Restore purchases work):-

CustomerInfo: <CustomerInfo:originalApplicationVersion=,latestExpirationDate=nil,activeEntitlements=[:],activeSubscriptions=[:],nonSubscriptionTransactions=[],requestDate=2021-11-04 16:47:10 +0000,firstSeen=2021-11-04 16:47:09 +0000,originalAppUserId=U1625795716907644928,entitlements=[:]>RevenueCat LastError: (null)
Userlevel 3
Badge +8

@taquitos Another user error, he is a subscriber but can’t see anything.

Good luck!

Ooof, this new error is actually on Apple’s server. They do some weird stuff with errors that makes it difficult to fully understand what the problem is sometimes, but we have a thread open on it and are going to work on a workaround, you can follow along: https://github.com/RevenueCat/purchases-ios/issues/392#issuecomment-804996692

I was able to chase down the exact response that was sent when your customer encountered: 

RevenueCat LastError: Error Domain=RevenueCat.ErrorCode Code=12 "Received malformed response from the backend." UserInfo={generated_by=<snip> getSubscriberData(appUserID:completion:), NSUnderlyingError=0x2823f5f50 {Error Domain=RevenueCat.UnexpectedBackendResponseSubErrorCode Code=8 "(null)" UserInfo={NSUnderlyingError=0x280c84c80 {Error Domain=RevenueCat.CustomerInfoError Code=1 "(null)"}

The json is ok and I can manually instantiate the objects with the exact response. I met with @Andy to discuss this and we walked through the code again. The only places where we could generate this error is if:
“subscriberData["first_seen"]” is empty, or the date format is incorrect.
OR:
“subscriberData["original_app_user_id"]” is nil.
Both of these conditions were ok in the response!
So that leaves us with some questions: what other sdks do you current use? Do you have any of your own Date extensions that you’re using? The thought is that maybe you’re using an SDK that could: 
1) swizzle some of the foundation date parsing stuff (we’ve seen it)
2) have the same named Date extension so runtime resolution of the extension is non-determinate.

We really appreciate you tracking this stuff down with us. At this point, I’ve added yet more error handling to a new pr, but I think something outside our control is going on since the exact json responses that are causing issues for you are not causing issues in my testing. If I could repro this, it would be so much easier 😔

 

 

 

Userlevel 3
Badge +8

@taquitos If this is the case, let me break in my code and debug if any of my NSDate extensions are being called.  Do you think this is a good strategy?

Meanwhile, another log from the same user who can’t restore his purchases.

 

I think that’s a solid plan. I”ll check into this log and get back to you with anything I find.

Userlevel 3
Badge +8

@taquitos I looked at your code:-

            guard let firstSeenDateString = subscriberData["first_seen"] as? String,

                  let firstSeenDate = dateFormatter.date(fromString: firstSeenDateString) else {

                return nil

            }

            self.firstSeen = firstSeenDate

            guard let originalAppUserIdString = subscriberData["original_app_user_id"] as? String else {

                return nil

            }

After you exit with nil, you call the logger.  I can’t access the logger and pass it to you (If I can please let me know how I can ask users to do that) but the error object that I attached is the one I can pass to you.  Is there a way you can add more info there so I can pass it to you?  I debugged your code and of course I see everything fine.  

Let me know how to proceed, my NSDate extension are not being called by your sdk.

I am guessing since this is a random thing, I saw empty CustomerInfo on my device from time to time, that this is not an SDK code that is causing it, it some garbage data coming from the server.

Happy to add any info if you think of any.

 

I just merged an update that will throw errors instead of returning `nil` in https://github.com/RevenueCat/purchases-ios/pull/937

I can’t release it to Beta just yet because we also just merged a large update that includes the beginning of StoreKit2 support and we need to test it a little bit more.

There is only 1 file to update if you wanted to build the SDK from the current beta tag with this.
 

 

Userlevel 3
Badge +8

@taquitos And anything I should be doing on my side of the code?

Badge

@taquitos 

 

We are running into this issue as well. Somehow we can’t form the json response correctly.

 

```

😿‼️ Unable to instantiate SubscriberData from json object: ["original_application_version": <null>, "non_subscriptions": { }, "first_seen": 2021-12-08T21:59:55Z, "original_purchase_date": <null>, "subscriptions": { }, "other_purchases": { }, "original_app_user_id": $RCAnonymousID:c8cab3a9cb4648d8828449e29194817d, "management_url": <null>, "entitlements": { }, "last_seen": 2021-12-08T21:59:55Z]

```

Userlevel 3
Badge +8

Adding two more log files with detailed errors.

Guys, this issue is frustrating to everyone.  Is there a way you connect with Apple to see what is going on?  I can connect with Apple as part of my development benefits but I don’t know how to follow up if they ask detailed questions (I didn’t write the code so I have no idea what is going on)!

It is still surprising to me that not all developers having the same issue, makes me wonder if there is a best practice I need to follow?  I don’t mind sharing the code that is responsible for the integration, I know the code was working and started to break just recently but maybe this can help?  If you are interested please let me know.

 

Again, thank you and Apple really suck!

@imougy and @Winston Du could both of y’all open a ticket for us at https://app.revenuecat.com/settings/support ? This is going to require some deeper digging, and having a ticket gives us a secure place to do that where you can share project code without worrying about exposing it to the public.

We’ll definitely will want to take a look at a few things related to your project setup/dependencies/platform support/etc. 

@imougy I’m currently baffled. I took one of the requests that are in your logs and the SDK had no issue parsing it. I think if we can test parsing and creating a CustomerInfo in your project from raw json, that might help us figure out what is going on. For example in your attached “log2.txt” I looked up the exact response we sent you from the server. I copied that into a test file and then loaded that the exact way our SDK does it. I expected the CustomerInfo parsing to fail the same way you are seeing it. That didn’t happen 😖 

 



 

Userlevel 3
Badge +8

@taquitos I opened a ticker as you mentioned.  Happy to share code or change it and see what is happening.  What should I do next?  It is a form that I filled and submitted, not sure what is next

I am attaching a legitimate error I hope from one user, the user didn’t complain but I always get an attachment with the latest error and I thought to share it with you guys.

@taquitos I opened a ticker as you mentioned.  Happy to share code or change it and see what is happening.  What should I do next?  It is a form that I filled and submitted, not sure what is next

I am attaching a legitimate error I hope from one user, the user didn’t complain but I always get an attachment with the latest error and I thought to share it with you guys.

That’s perfect, I think @cody is going to dig in some more. 

 

Badge

@taquitos

Is there a place in the latest sdk release that logs the json in full utf8? (We only are logging the swift dictionary object right now...)
 

The failure I have is at:

https://github.com/RevenueCat/purchases-ios/blob/aa18f434441b7e59e30a49810f0d9e3284b1873c/Purchases/Public/CustomerInfo.swift#L181


Can you also link a test project containing your deserialization test code?

Userlevel 3
Badge +8

@Winston Du good questions.  I get those logs that I posted by saving the error code in memory and when users contact me I embed those error codes so I can see what is going on.  It will be great if there is an api we call to get the internal state of the SDK so we can pass it along. 

@imougy I’m a huge fan of this suggestion. Could you open a new topic here and include what you’d like the API to look like and what you’d want to get from it? I bet there are other folks who might want to add their $0.02 😄

Badge

@taquitos ,

 

After taking a look at our code, we noticed we are using the Datadog SDK, which has a similar extension on ISO8601Formatter signature as the RevenueCat SDK (both of them have the class conform to a protocol of the same name)  (https://github.com/DataDog/dd-sdk-ios/blob/9cdb8fe7615949554e8a6af2ddbe2857050fed35/Sources/Datadog/Core/Utils/DateFormatting.swift)

Do you think this could cause any issues?

Oh wow! Yeah, maybe that could do it. We recently rewrote our iso8601DateFormatter to use the newer `ISO8601DateFormatter`, but haven’t released a beta with it include: https://github.com/RevenueCat/purchases-ios/blob/main/Purchases/FoundationExtensions/DateFormatter%2BExtensions.swift

We’re still finishing up the last bit of StoreKit2 additions and then we’ll release another Beta. Are you able to test out this theory building from `main`?

Badge

@taquitos ,

I didn’t even realize that change was not in beta-7! So ignore my previous post. Because it turns out the rewrite wasn’t the issue, it was actually a solution!
 

@imougy 

The original issue is resolved by using the recent change to use the `ISO8601DateFormatter`. https://github.com/RevenueCat/purchases-ios/issues/1096#issuecomment-997470529

It seems the original `iso8601dateformatter` code had subtle buggy issues for users with unconventional calendar or date/time settings for non-US locales. After we used a version of the SDK with the rewritten DateFormatter, our issues were resolved for our users.

Userlevel 3
Badge +8

@Winston Du in my app, I myself get affected from time to time, I get empty customerInfo and need to restore purchases.  I have US local.  The randomness of the issue is a puzzle to me, unless some dates are parsed and others are not!

Anyway, I am eagerly awaiting any fix to test.

@Winston Du  Thanks for the follow up and I hope I can report good news when I get this change. @taquitos please keep me in touch so I can get this change.

@Winston Du  and @imougy I’ve made a tag and the release is happening. Should be done within the next 30 minutes 🎉
https://github.com/RevenueCat/purchases-ios/releases/tag/4.0.0-beta.8

If you’re using SPM, you should be good to go now 😄 Thank you @Winston Du for the assist!

Userlevel 3
Badge +8

I installed Beta.8 and played with it on my device.  After many launches on my device, I get an instance where customerInfo has no entitlements and no error (I do have some entitlements).  After the app quit and relaunch, the entitlements came fine.  I am releasing the app anyway, pending Apple approval now.

One of the users told me that Restore Purchases didn’t work for him, attached is his error, I told him to change to region to USA, his region was some where in Netherland, after he changed the region, the Restore worked fine.

Will keep you updated...

Reply