Support DEFERRED mode#985
Conversation
42b6d40 to
79f6312
Compare
dalshamaa
left a comment
There was a problem hiding this comment.
Looks good to my non-expert eye!
There was a problem hiding this comment.
Is this true? Wouldn't the onPurchasesUpdated callback always get called with the old transaction, even if we're using the deprecated flow?
There was a problem hiding this comment.
For deferred purchases the purchases list will be empty. For regular purchases or other upgrades, the purchases will contain the new purchase
c306a51 to
d359fa1
Compare
There was a problem hiding this comment.
For deferred purchases the purchases list will be empty. For regular purchases or other upgrades, the purchases will contain the new purchase
|
Actually tests are failing 😄 |
|
I was getting suspicious by the behaviour of the DEFERRED purchase listener so I dug a bit deeper. Looks like the behavior for According to Google's documentation as of May 23, 2022:
Which changed to this sometime before July 5, 2022:
I could not find an explicit mention of this in the BL5 release notes, but the docs change coincides more or less with the official release of Billing Library 5.0 on May 11, 2022 I'm going to review the places where we may be making the old assumption and make changes accordingly. |
There was a problem hiding this comment.
Entirely removed the special handling for the case where purchases are empty:
- It was only being handled when using the deprecated purchase methods.
- In the new purchase method callback,
StoreTransactionis not nullable. - Since Billing Library 5, the transactions list will contain the transaction for the old product. See comment.
We could make the new purchase method callback have a nullable transaction parameter, and handle the case where purchases.isEmpty() for both old and new purchase methods. But supposedly that should not be happening in BL5.
Thoughts?
There was a problem hiding this comment.
Hmm in the BillingWrapper class we are still forwarding an empty list of purchases, even though it shouldn't happen in BC5. If that unexpected situation happened, we wouldn't call the callbacks after removing this if I'm not wrong, so it would basically get stuck.
I think we should call the error callback when this happens, at least until we are certain that this won't happen, and at that point, we should remove that code from BillingWrapper
There was a problem hiding this comment.
We had 4 separate but very similar tests for DEFERRED mode, which I'm not entirely sure were even working properly (e.g. ProrationMode.DEFERRED was not even passed).
I simplified them into two tests, each using the old and the new purchase methods respectively.
There was a problem hiding this comment.
Added the same comment in both pieces of code where we do special handling for DEFERRED mode product id. Open to suggestions.
tonidero
left a comment
There was a problem hiding this comment.
Left a comment but looking good!
There was a problem hiding this comment.
Maybe we could add a log if this is an unexpected situation now?
There was a problem hiding this comment.
After more carefully reading the code, I realized we were already handling this case in the error handling code at the bottom of the method. Simply removing the special case handling means we'll call the error handler as expected.
There was a problem hiding this comment.
Hmm in the BillingWrapper class we are still forwarding an empty list of purchases, even though it shouldn't happen in BC5. If that unexpected situation happened, we wouldn't call the callbacks after removing this if I'm not wrong, so it would basically get stuck.
I think we should call the error callback when this happens, at least until we are certain that this won't happen, and at that point, we should remove that code from BillingWrapper
…on stays the same for current enum values.
…change. Starting with Billing Client 5, the listener will always contain the old transaction.
Left only two tests: one using the old deprecated purchase method, and one using the new one.
…the existing error callback code.
2391acf to
03f1f91
Compare
| @Test | ||
| fun `purchasesUpdatedCalls are forwarded with empty list if result is ok but with a null purchase`() { | ||
| val slot = slot<List<StoreTransaction>>() | ||
| fun `purchasesUpdatedCalls call the error callback if result is ok but with a null purchase`() { |
There was a problem hiding this comment.
Updated test to reflect the new expected behavior.
tonidero
left a comment
There was a problem hiding this comment.
Looks good! Just left a comment to try to improve the error message in the case we receive a null/empty list of purchases.
…ingResult with a Null purchases list
Codecov Report
@@ Coverage Diff @@
## main #985 +/- ##
==========================================
+ Coverage 85.34% 85.41% +0.06%
==========================================
Files 168 168
Lines 5984 5977 -7
Branches 835 832 -3
==========================================
- Hits 5107 5105 -2
+ Misses 546 544 -2
+ Partials 331 328 -3
|
**This is an automatic release.** ### New Features * Support DEFERRED mode (#985) via swehner (@swehner) * Add completion callback to syncPurchases API (#1002) via Toni Rico (@tonidero) ### Bugfixes * Workaround bug in android 4 for JSON objects with List<String> (#942) via Andy Boedo (@aboedo) ### Dependency Updates * Bump fastlane-plugin-revenuecat_internal from `fe45299` to `13773d2` (#1015) via dependabot[bot] (@dependabot[bot]) ### Other Changes * Bump dokka to 1.8.10 to support Gradle 8 (#1009) via Toni Rico (@tonidero) * Disable offline entitlements temporarily (#1023) via Toni Rico (@tonidero) * Fix integration tests in CI (#1019) via Toni Rico (@tonidero) * Add offline entitlements integration tests (#1006) via Toni Rico (@tonidero) * Disable offline entitlements in observer mode (#1014) via Toni Rico (@tonidero) * Extracts setup and teardown to BasePurchasesTest (#1011) via Cesar de la Vega (@vegaro) * Support forcing server errors for tests (#1008) via Toni Rico (@tonidero) --------- Co-authored-by: revenuecat-ops <ops@revenuecat.com> Co-authored-by: Toni Rico <antonio.rico.diez@revenuecat.com>
Support DEFERRED Proration mode.
One problem is that the returned purchase is for the old product, not the new one, so all the callback need to use the replaced productId.
Checklist
purchases-iosand hybridsDescription
Use old productId in callbacks for when proration mode is deferred.