Refactor presentedOfferingIdentifier into presentedOfferingContext object#1612
Conversation
| ReplaceWith("presentedOfferingContext.offeringIdentifier"), | ||
| ) | ||
| val offering: String | ||
| get() = presentedOfferingContext.offeringIdentifier ?: "" |
There was a problem hiding this comment.
I made the presentedOfferingContext have a nullable offeringIdentifier instead of making the presentedOfferingContext nullable in StoreProduct/SubscriptionOption in case we could have non-offering related context, which is probably not the case right now... But this forces us to default to something here as a fallback. It should never be null right now though in the Package.
There was a problem hiding this comment.
I like this! I think this makes sense 👍
There was a problem hiding this comment.
hmm I think it makes sense for StoreProduct/SubscriptionOption, but with this there's no way to indicate that a package will always have an offering and a package is always going to have an offering. Do we need to replace offering in Package with presentedOfferingContext? I think we can leave this as is offering: String and only replace presentedOfferingIdentifier in StoreProduct and SubscriptionOption? We access the presentedOfferingContext through the products, and not the packages.
There was a problem hiding this comment.
Hmm it's a good point... the only difference is going to be that the offering is not nullable in the Package... However, It feels nicer to me if we have the same format in all 3 places... If we don't have this data at the Package level we will need to access it through the StoreProduct when purchasing, which seems slightly less clean...
What do you think about leaving the offering property undeprecated here in the Package? It would be duplicated with the one in presentedOfferingContext but that way we can keep the non-nullability here
There was a problem hiding this comment.
I guess my question is if we need a presentedOfferingContext at all in Package. Is it ever going to be different than the offering value? I guess we can add a different way of getting Packages in the future, which would indeed make offering not nullable and create the need of a presentedOfferingContext, but maybe we can add that property whenever we need. I just think adding it right now makes the API confusing and doesn't add value. Maybe I am missing context
There was a problem hiding this comment.
Actually... What if we make it a sealed class that only has an implementation right now? That way we can keep the original nullabilities. Can you remind me what other type of data we are adding to the PresentedOfferingContext?
There was a problem hiding this comment.
@joshdholtz I was chatting live with @vegaro about this one... In the end, we believe it would be better to make the offeringIdentifier not nullable inside the PresentedOfferingContext so we can make the PresentedOfferingContext not nullable in Package but nullable in StoreProduct/SubscriptionOption. Do you think we will (now or in the future) have data like this without having an offering id?
My original reason to make it nullable was to provide more flexibility in the future in case we have some of this data without an offering id, but I don't think that would happen for now at least, so it makes sense to better reflect the current model.
Let us know what you think!
| ) : PurchaseResponseListener { | ||
|
|
||
| private val productTypes = mutableMapOf<String, ProductType>() | ||
| private val presentedOfferingsByProductIdentifier = mutableMapOf<String, String?>() |
There was a problem hiding this comment.
I removed this because it seems it wasn't used. Seems we were passing the offering id in the AmazonBilling class instead.
| * Context of the offering that was presented when making the purchase. | ||
| */ | ||
| val presentedOfferingIdentifier: String?, | ||
| val presentedOfferingContext: PresentedOfferingContext?, |
There was a problem hiding this comment.
I had doubts on this... Note that it's nullable here but not nullable in the Package/StoreProduct/SubscriptionOption. It will be null here when it can't find any information about the context (usually restores and such) vs having a context with empty data when the origin of the purchase is through a product/we don't have offering data.
Lmk if you think we should standardize this somehow and we can chat, but I thought it was ok like this for now.
There was a problem hiding this comment.
I think this is fine to be nullable here! Forcing an object before the transaction makes it a cleaner (especially when copying the object down into subscription options. I probably would have done the same here in making it nullable in the transaction 👍
joshdholtz
left a comment
There was a problem hiding this comment.
This is looking good! Thank you so much for jumping on this so quickly 👍
| ReplaceWith("presentedOfferingContext.offeringIdentifier"), | ||
| ) | ||
| val offering: String | ||
| get() = presentedOfferingContext.offeringIdentifier ?: "" |
There was a problem hiding this comment.
I like this! I think this makes sense 👍
| * Context of the offering that was presented when making the purchase. | ||
| */ | ||
| val presentedOfferingIdentifier: String?, | ||
| val presentedOfferingContext: PresentedOfferingContext?, |
There was a problem hiding this comment.
I think this is fine to be nullable here! Forcing an object before the transaction makes it a cleaner (especially when copying the object down into subscription options. I probably would have done the same here in making it nullable in the transaction 👍
…lable in storeproduct and subscriptionOption
| data class GoogleStoreProduct( | ||
| data class GoogleStoreProduct | ||
| @JvmOverloads | ||
| @Deprecated( |
There was a problem hiding this comment.
Quick note about this deprecation. I was running into a lot of issues trying to add the new parameter while trying to keep retrocompatibility... In the end, I'm deprecating the main constructor and adding a new one which is internal only.
Reason was that there were a lot of overload conflicts, specially in Java, where String can be null and it was making the API tests fail.
IMO, we should make all these constructors internal in the future. If we want to allow devs to create them, then I would suggest using the Builder pattern instead... Much easier to add/deprecate things and allows us to keep flexibility for the constructor.
|
Ok this is ready for another review @joshdholtz @vegaro |
joshdholtz
left a comment
There was a problem hiding this comment.
This looks good to me! Two minor questions but otherwise LGTM 💪 Thanks so much for doing this!
**This is an automatic release.** ### New Features * Add setDisplayDismissButton to PaywallView (#1608) via Cesar de la Vega (@vegaro) ### Bugfixes * Fix runtime crash when using amazon and targetting android 14 (#1622) via Toni Rico (@tonidero) * Paywalls: No-op on all view model methods in the Loading paywall screen (#1617) via Toni Rico (@tonidero) * Fix safe insets on full screen (#1613) via Cesar de la Vega (@vegaro) ### Other Changes * Change default paywall background with a lower quality image (#1623) via Toni Rico (@tonidero) * Fix load shedder integration tests (#1618) via Cesar de la Vega (@vegaro) * Refactor `presentedOfferingIdentifier` into `presentedOfferingContext` object (#1612) via Toni Rico (@tonidero) * [External] Update russian and kazakh translations (#1577 by @janbolat) (#1616) via Toni Rico (@tonidero) Co-authored-by: revenuecat-ops <ops@revenuecat.com>
Description
With some new incoming features, we will need to pass more context information about where the package/product was obtained from. This PR prepares for that by adding a new class
PresentedOfferingContextwhich right now only holds thepresentedOfferingIdentifierbut that we can add more info later on that allows to pass more information to our servers.