Fix: Clear in-memory offerings cache on locale override to prevent stale paywall data#3225
Merged
Merged
Conversation
…aywall data When `overridePreferredUILocale` is called, the cached offerings may contain localized data for the old locale. Without clearing the cache, a subsequently presented paywall could render stale data via the stale-while-revalidate path. The fix clears the in-memory offerings cache and re-fetches, both gated behind the existing rate limiter. The disk cache is preserved as a fallback for network errors. Made-with: Cursor
2 tasks
Made-with: Cursor
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3225 +/- ##
==========================================
+ Coverage 79.18% 79.34% +0.15%
==========================================
Files 356 356
Lines 14273 14276 +3
Branches 1945 1945
==========================================
+ Hits 11302 11327 +25
+ Misses 2166 2144 -22
Partials 805 805 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Mar 16, 2026
**This is an automatic release.** ## RevenueCat SDK ### 🐞 Bugfixes * Fix & Standardize Galaxy Date Parsing Edge Cases (#3216) via Will Taylor (@fire-at-will) * Fix addSuccessfullyPostedToken for new purchases in PostPendingTransactionsHelper (#3239) via Facundo Menzella (@facumenzella) * [Galaxy]: Fix race condition when fetching Galaxy products (#3213) via Will Taylor (@fire-at-will) * Fixes double padding in PaywallActivity on Android 15+ when `edgeToEdge` parameter is false (#3227) via Cesar de la Vega (@vegaro) ## RevenueCatUI SDK ### 🐞 Bugfixes * Fix bold text not rendering in Markdown lists (#3228) via Cesar de la Vega (@vegaro) * Fix: Clear in-memory offerings cache on locale override to prevent stale paywall data (#3225) via Antonio Pallares (@ajpallares) ### Paywallv2 #### ✨ New Features * Feature: Update default paywall (#3133) via Jacob Rakidzich (@JZDesign) #### 🐞 Bugfixes * Fix V2 paywall safe area in landscape mode (#3221) via Cesar de la Vega (@vegaro) ### 🔄 Other Changes * Run integration tests on all branches (#3242) via Toni Rico (@tonidero) * Migrate Firebase Test Lab jobs to CircleCI emulators (#3238) via Toni Rico (@tonidero) * Run metalava on galaxy module in test-galaxy job (#3235) via Will Taylor (@fire-at-will) * Add offering_id to custom paywall impression event (#3230) via Rick (@rickvdl) * Cache isAutoRenewing to detect subscription changes without syncPurchases (#3198) via Facundo Menzella (@facumenzella) * Bump fastlane-plugin-revenuecat_internal from `e146447` to `3e8c384` (#3233) via dependabot[bot] (@dependabot[bot]) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk release housekeeping: version string bumps and documentation/deployment path updates with no functional runtime logic changes beyond the exposed version constant. > > **Overview** > Publishes the `9.26.0` release by removing `-SNAPSHOT` across build/version metadata (root `VERSION_NAME`, `.version`, `Config.frameworkVersion`, and sample/test app dependency pins). > > Updates release documentation artifacts by adding the `9.26.0` notes to `CHANGELOG.md`/`CHANGELOG.latest.md`, switching docs deployment in CircleCI to sync `docs/9.26.0` to S3, and updating `docs/index.html` to redirect to the new version. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0a30a45. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
purchases-iosand hybridsMotivation
overridePreferredUILocale()sets the locale synchronously and triggers an offerings re-fetch in the background, but does not clear the in-memory offerings cache. When a paywall is presented immediately after, the stale-while-revalidate path returns the cached offerings (fetched with the old locale'sX-Preferred-Localesheader) and the paywall renders the wrong language. On the second presentation the cache is fresh and the correct locale appears.iOS counterpart: RevenueCat/purchases-ios#6446
Description
When
overridePreferredUILocaleis called and the rate limiter allows, we now clear the in-memory offerings cache before re-fetching offerings. This ensures that any subsequentofferings()call (e.g., from a paywall) finds no cached data and waits for the fresh network response with the correct locale header, rather than returning stale data.clearInMemoryOfferingsCache()toOfferingsCacheandOfferingsManager— clears the in-memory offerings instance and locale tags, but preserves the disk cache as a network-error fallback.fetchOfferingsWithRateLimittoclearCacheAndFetchOfferingsWithRateLimit— both the cache clear and the re-fetch are gated by the rate limiter so neither happens when rate-limited.fetchCurrent = truefrom the offerings fetch since the in-memory cache is already cleared beforehand.This is purely an internal behavior change with no public API impact.
Note
Medium Risk
Changes offerings caching behavior during locale overrides by clearing in-memory state and altering fetch semantics; could affect when/which cached offerings are returned, but is scoped and covered by new unit tests.
Overview
Fixes stale paywall language after
overridePreferredUILocale()by clearing the in-memory Offerings cache before refetching, ensuring subsequentgetOfferings()calls don’t immediately vend offerings fetched under the previous locale.Adds
clearInMemoryOfferingsCache()toOfferingsCache/OfferingsManager(clears in-memory offerings + cached locale tags while preserving disk cache for fallback), and updates the locale-override rate-limited refresh path to gate both the cache clear and fetch; tests were added to cover ordering, unchanged-locale behavior, rate limiting, and failure cases.Written by Cursor Bugbot for commit 914cbd7. This will update automatically on new commits. Configure here.