Skip to content

BC8 migration#2477

Merged
tonidero merged 20 commits into
mainfrom
bc8-migration
Jul 4, 2025
Merged

BC8 migration#2477
tonidero merged 20 commits into
mainfrom
bc8-migration

Conversation

@tonidero

@tonidero tonidero commented Jul 1, 2025

Copy link
Copy Markdown
Contributor

@tonidero tonidero added pr:breaking Changes that are breaking pr:other labels Jul 1, 2025
@codecov

codecov Bot commented Jul 1, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 60.52632% with 30 lines in your changes missing coverage. Please review.

Project coverage is 78.33%. Comparing base (0eee76f) to head (d9606cd).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...hases/google/usecase/QueryProductDetailsUseCase.kt 17.64% 12 Missing and 2 partials ⚠️
.../com/revenuecat/purchases/google/BillingWrapper.kt 75.00% 8 Missing ⚠️
...n/kotlin/com/revenuecat/purchases/google/errors.kt 70.00% 4 Missing and 2 partials ⚠️
...n/com/revenuecat/purchases/amazon/AmazonBilling.kt 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2477      +/-   ##
==========================================
- Coverage   78.72%   78.33%   -0.39%     
==========================================
  Files         289      286       -3     
  Lines       10519    10432      -87     
  Branches     1509     1500       -9     
==========================================
- Hits         8281     8172     -109     
- Misses       1590     1614      +24     
+ Partials      648      646       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

) {
log(LogIntent.DEBUG) { RestoreStrings.QUERYING_PURCHASE_WITH_TYPE.format(productId, productType.name) }
queryAllPurchases(
queryPurchases(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in behavior in Amazon... but I think this is fine, since this method was only used for upgrades/downgrades which is not really supported in Amazon. I just changed the implementation to make it more sense with the new method name.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to test this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, as you can see here, we early exit from the purchase if the developer gives us any replacement information (we actually should improve that, since it would actually keep the call forever without returning an error 😬)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, yea that's something we should improve. Can be a separate PR though.

StatusCode.INVALID_PRODUCT_ID_FORMAT -> "INVALID_PRODUCT_ID_FORMAT"
StatusCode.NO_ELIGIBLE_OFFER -> "NO_ELIGIBLE_OFFER"
else -> "UNKNOWN_STATUS_CODE: $statusCode"
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was interesting, for now I'm just logging to console, but in the future it might be useful to track this information with diagnostics or something else and expose it in the dashboard in case there are issues.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a fun interview problem 😅


// Google Play Billing Library 8.0 removed APIs to query historical purchases.
// This method will from now on only return active purchases in Google Play.
// However, in Amazon, it will still return historical purchases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I wasn't sure whether to just remove this method entirely... but I wanted to keep Amazon having the same functionality as long as it's possible and since this is abstracting the Store, I preferred to keep it. Lmk if you think otherwise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to make this actual documentation of the method, so it's surfaced by the IDE?

    /**
     * Google Play Billing Library 8.0 removed APIs to query historical purchases.
     * This method will from now on only return active purchases in Google Play.
     * However, in Amazon, it will still return historical purchases.
     */


@SuppressWarnings("LongParameterList")
abstract fun findPurchaseInPurchaseHistory(
abstract fun findPurchaseInActivePurchases(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was only being used for upgrades/downgrades. I'm not sure why were were looking in the purchase history, when upgrades/downgrades are only possible with active subs AFAIK. Now we only check for active purchases.

@tonidero tonidero marked this pull request as ready for review July 2, 2025 07:45
@tonidero tonidero requested review from a team and vegaro July 2, 2025 07:46

@JayShortway JayShortway left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking care of this! Approved as far as I'm concerned, but since this is pretty much the change of the year, we might want another pair of eyes on it.

Comment on lines -13 to -15
* **Important**: until multi-line subscriptions are released,
* we assume that there will be only a single sku in the purchase.
* https://android-developers.googleblog.com/2021/05/whats-new-in-google-play-2021.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well well well 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 years later...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

Comment thread gradle/libs.versions.toml
StatusCode.INVALID_PRODUCT_ID_FORMAT -> "INVALID_PRODUCT_ID_FORMAT"
StatusCode.NO_ELIGIBLE_OFFER -> "NO_ELIGIBLE_OFFER"
else -> "UNKNOWN_STATUS_CODE: $statusCode"
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a fun interview problem 😅


// Google Play Billing Library 8.0 removed APIs to query historical purchases.
// This method will from now on only return active purchases in Google Play.
// However, in Amazon, it will still return historical purchases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to make this actual documentation of the method, so it's surfaced by the IDE?

    /**
     * Google Play Billing Library 8.0 removed APIs to query historical purchases.
     * This method will from now on only return active purchases in Google Play.
     * However, in Amazon, it will still return historical purchases.
     */

) {
log(LogIntent.DEBUG) { RestoreStrings.QUERYING_PURCHASE_WITH_TYPE.format(productId, productType.name) }
queryAllPurchases(
queryPurchases(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to test this?

@ajpallares ajpallares left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a look. Nothing to object! But I'll leave approval to others with more knowledge 🙏


override fun queryAllPurchases(
appUserID: String,
onReceivePurchaseHistory: (List<StoreTransaction>) -> Unit,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe these parameters names should be updated.

I wonder if queryAllPurchases can just be queryPurchases now as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I left queryAllPurchases as it is... The thing is that Amazon can still query for all products, so I think restore/sync should still do that in Amazon. In that case, we need to differentiate between both... (I guess we could also unify both methods and add a parameter, but I kept it separate for now to minimize the changes and left a comment as seen here

)
} catch (e: NoClassDefFoundError) {
throw NoCoreLibraryDesugaringException(e)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did they finally fix this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! I was able to test on the device we used to test the issues. Very easy to repro in main. No issues with BC8 🙌

.firstOrNull { it.getInt(it) == this }
?.name
?: "$this"
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume getOnPurchasesUpdatedSubResponseCodeName will barely get called but since it's using reflection, you could maybe create a static map that this function can access when called

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it will get called on every purchase attempt... And yeah, might be better to create a map... I just followed what we do for the responseCode itself, but I think creating a map ourselves feels better yeah... Will do the change, and I might change that other mapping we do while I'm at it.

}
logErrorIfIssueBuildingBillingParams(received)
received.takeUnless { it.isEmpty() }?.forEach {
received.unfetchedProductList.takeIf { it.isNotEmpty() }?.let {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this unfetchedProductList is nice

We could have somthing similar in Offerings

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we might want to expose this somehow... But we should probably agree on what API to use. For now, I'm just logging the reason for it to be unfetched, but I also think it might be good to track it with diagnostics, and even give this information in the dashboard.

@tonidero tonidero enabled auto-merge July 4, 2025 11:02
@tonidero tonidero added this pull request to the merge queue Jul 4, 2025
@tonidero tonidero removed this pull request from the merge queue due to a manual request Jul 4, 2025
@tonidero tonidero enabled auto-merge July 4, 2025 12:05
@tonidero tonidero added this pull request to the merge queue Jul 4, 2025
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 4, 2025
@tonidero tonidero added this pull request to the merge queue Jul 4, 2025
Merged via the queue into main with commit 2270d6a Jul 4, 2025
14 checks passed
@tonidero tonidero deleted the bc8-migration branch July 4, 2025 14:20
tonidero added a commit that referenced this pull request Jul 9, 2025
@tonidero tonidero removed the pr:breaking Changes that are breaking label Jul 9, 2025
@tonidero

tonidero commented Jul 9, 2025

Copy link
Copy Markdown
Contributor Author

Removing breaking label since we're making a new release without this for now, so automations are able to continue and make a normal release before we ship this. Reverted in #2501

tonidero added a commit that referenced this pull request Jul 9, 2025
github-merge-queue Bot pushed a commit that referenced this pull request Jul 9, 2025
**This is an automatic release.**

## RevenueCat SDK
### ✨ New Features
* feat(purchases): Add setPostHogUserId() method to Purchases API
(#2495) via Hussain Mustafa (@hussain-mustafa990)
### 🐞 Bugfixes
* Improves button progress indicator size calculation. (#2485) via
JayShortway (@JayShortway)

### 🔄 Other Changes
* Revert "BC8 migration (#2477)" (#2501) via Toni Rico (@tonidero)
* Add codelab instructions on README file (#2489) via Jaewoong Eum
(@skydoves)
* Use collectAsStateWithLifecycle instead of collectAsState in Compose
(#2488) via Jaewoong Eum (@skydoves)
* Improve Composable stabilities (#2478) via Jaewoong Eum (@skydoves)
* [AUTOMATIC][Paywalls V2] Updates paywall-preview-resources submodule
(#2486) via RevenueCat Git Bot (@RCGitBot)
* BC8 migration (#2477) via Toni Rico (@tonidero)
* Fixes building sample apps with SNAPSHOT dependencies (#2483) via
JayShortway (@JayShortway)
* [AUTOMATIC][Paywalls V2] Updates paywall-preview-resources submodule
(#2484) via RevenueCat Git Bot (@RCGitBot)

Co-authored-by: revenuecat-ops <ops@revenuecat.com>
@tonidero tonidero mentioned this pull request Jul 10, 2025
github-merge-queue Bot pushed a commit that referenced this pull request Jul 10, 2025
This reverts commit 34c61a3.

### Description
Reapplies the changes originally from #2477 that were reverted in #2501
to allow making a release in the current major.

Migrates to BC8:
https://developer.android.com/google/play/billing/release-notes#8-0-0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants