Add non paid revenue reporting infra#2728
Conversation
| private val appSessionID: UUID = Companion.appSessionID, | ||
| private val legacyEventsFileHelper: EventsFileHelper<PaywallStoredEvent>, | ||
| private val fileHelper: EventsFileHelper<BackendStoredEvent>, | ||
| private val adFileHelper: EventsFileHelper<BackendStoredEvent.Ad>, |
There was a problem hiding this comment.
This PR is still WIP but this is the last approach I mentioned here. I believe it minimizes the code duplication quite a bit. Wdyt @polmiro @JayShortway ?
There was a problem hiding this comment.
Lmk what you think about this approach (different track methods for different types of events). I think we could also pass the URL as a parameter to the events manager and create multiple event managers. However, I don't think the current approach is that error-prone since the types of events for ads and current are different.
There was a problem hiding this comment.
I agree with having different storage files given they function as a queue that gets cleared independently.
When it comes to event managers I am a bit in the middle, let me share my thoughts see what you think:
- Tracking:
- From a caller perspective all the event tracking calls should be going through the same object. And how that gets delivered is an implementation detail. This hints to me that we should have a single events manager when it comes to tracking.
- Flushing:
- Paywall events flushing: There are a couple of trigger points that specific only to the paywall events. These in my opinion should only go to the event manager that handles paywall events and not the one handling ad events.
- Ad events flushing: Given the amount of events, there may be added complexities to handle in the ad event manager (just throwing some rough potential ideas):
- sending more one batch of events at a time.
- having some sort of time-based flushing to avoid waiting too long
- having some event count flushing to prevent accumulating too many events.
- Maybe these apply to both event managers, maybe not, I am not sure.
- These hint to me that we may want separate events manager when it comes to flushing.
There was a problem hiding this comment.
Hmm well, regarding flushing behavior, if we want to have different behavior between ad and paywalls&customerCenter events, having it be 2 instances of the EventManger might be a bit trickier... Right now the EventManger, syncs only the oldest 50 events for paywalls/customer center events. But maybe we want to perform multiple requests for Ads, if there are more than 50 events, so they don't accumulate, which would require changes inside the EventManager...
Having said that, I think it would be better to try to keep the logic for flushing the same/similar, since the events seem relatively similar in importance. At this point, I think I could go either way. Will implement the 2 instances of the EventManager though, since it might be slightly cleaner 👍
There was a problem hiding this comment.
I agree with the thoughts, this is why I wanted to separate this part in a different PR since it seems prone to require some more back and forth.
| private val appSessionID: UUID = Companion.appSessionID, | ||
| private val legacyEventsFileHelper: EventsFileHelper<PaywallStoredEvent>, | ||
| private val fileHelper: EventsFileHelper<BackendStoredEvent>, | ||
| private val adFileHelper: EventsFileHelper<BackendStoredEvent.Ad>, |
There was a problem hiding this comment.
Lmk what you think about this approach (different track methods for different types of events). I think we could also pass the URL as a parameter to the events manager and create multiple event managers. However, I don't think the current approach is that error-prone since the types of events for ads and current are different.
| @get:Synchronized | ||
| @set:Synchronized | ||
| private var flushInProgress = false | ||
| private var flushInProgress = AtomicBoolean(false) |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2728 +/- ##
==========================================
+ Coverage 77.98% 78.15% +0.17%
==========================================
Files 320 323 +3
Lines 12520 12706 +186
Branches 1727 1743 +16
==========================================
+ Hits 9764 9931 +167
- Misses 2028 2038 +10
- Partials 728 737 +9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| /** | ||
| * Tracks ad-related events such as ad displays, opens, and revenue. | ||
| */ | ||
| @InternalRevenueCatAPI |
There was a problem hiding this comment.
Note that I'm marking this as @InternalRevenueCatAPI, so developers would need to explicitedly opt-in to use it, but it can still theoretically be used in the wild (very unlikely), unlike in iOS, where it's behind a compiler flag. I can add a compiler flag to disable tracking at all until we're ready, but I was wondering what the plan is to ship this? @polmiro
There was a problem hiding this comment.
What there be the risks of someone using this? From the stability of public APIs perspective, I think this is OK, even if we want to make changes to it while marked as @InternalRevenueCatAPI
There was a problem hiding this comment.
It's behind a feature flag in the backend as well, so it would basically have events that would fail to send, and since it's with a 4xx, it would mark them as sent, so I think very low right now.
| /** | ||
| * Tracks ad-related events such as ad displays, opens, and revenue. | ||
| */ | ||
| @InternalRevenueCatAPI |
There was a problem hiding this comment.
What there be the risks of someone using this? From the stability of public APIs perspective, I think this is OK, even if we want to make changes to it while marked as @InternalRevenueCatAPI
Removed WIP comment regarding event flushing frequency.
**This is an automatic release.** > [!WARNING] > If you don't have any login system in your app, please make sure your one-time purchase products have been correctly configured in the RevenueCat dashboard as either consumable or non-consumable. If they're incorrectly configured as consumables, RevenueCat will consume these purchases. This means that users won't be able to restore them from version 9.0.0 onward. > Non-consumables are products that are meant to be bought only once, for example, lifetime subscriptions. ## RevenueCat SDK ### 🐞 Bugfixes * Restore Purchases config automatically in CustomerCenter (#2867) via Facundo Menzella (@facumenzella) * Handle error reading `errorStream` in some devices (#2865) via Toni Rico (@tonidero) * [MON-1122] Revert variable rounding logic to not round up (#2857) via Pol Piella Abadia (@polpielladev) ## RevenueCatUI SDK ### Paywallv2 #### 🐞 Bugfixes * Select default package on Sheet dismissal (#2861) via Cesar de la Vega (@vegaro) ### Customer Center #### ✨ New Features * CC-581 | Allow for support ticket creation (#2810) via Rosie Watson (@RosieWatson) ### 🔄 Other Changes * Bump fastlane-plugin-revenuecat_internal from `7328ea7` to `efca663` (#2864) via dependabot[bot] (@dependabot[bot]) * Bump fastlane from 2.228.0 to 2.229.0 (#2863) via dependabot[bot] (@dependabot[bot]) * Bump fastlane-plugin-revenuecat_internal from `083ced9` to `7328ea7` (#2862) via dependabot[bot] (@dependabot[bot]) * Runs plugin actions from correct directory (#2858) via JayShortway (@JayShortway) * Flush multiple event batches (#2842) via Toni Rico (@tonidero) * Add file size limit to events tracking files (#2841) via Toni Rico (@tonidero) * Make events manager be supported in Android < 24 (#2854) via Toni Rico (@tonidero) * Add non paid revenue reporting infra (#2728) via Toni Rico (@tonidero) * Fix backend integration tests (#2860) via Toni Rico (@tonidero) * Track `connection_error_reason` property in diagnostics (#2855) via Toni Rico (@tonidero) * Uses some git+GitHub lanes from Fastlane plugin (#2856) via JayShortway (@JayShortway) * Add client side timeout logic for endpoints that support fallback URLs (#2807) via Toni Rico (@tonidero) * [EXTERNAL] Fix deprecation warnings in examples module (#2852) contributed by @gojoel (#2853) via Toni Rico (@tonidero) * Bump fastlane-plugin-revenuecat_internal from `9f78bb9` to `083ced9` (#2848) via dependabot[bot] (@dependabot[bot]) Co-authored-by: revenuecat-ops <ops@revenuecat.com>
…2871) ### Description This is a follow-up from #2728 In iOS, we're passing an object to the track methods for non paid revenue tracking, but we were passing the individual parameters in Android. After thinking about it, passing an object allows for better extensibility, so modifying the API for android. This is technically a breaking change, but the API is still internal, so it should be ok.
Description
Implements ad event tracking infrastructure for RevenueCat. This provides the client-side foundation needed to report ad impressions, clicks, and revenue alongside subscription data for comprehensive LTV tracking.
In follow-up PRs: