-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Description
Checklist before submitting a bug report
- I've updated to the latest released version of the SDK
- I've searched for existing Github issues
- I've looked for existing answers on Stack Overflow, the Facebook Developer Community Forum and the Facebook Developers Group
- I've read the Code of Conduct
- This issue is not security related and can safely be disclosed publicly on GitHub
Java version
1.8
Android version
13
Android SDK version
33
Installation platform & version
Gradle plugin 7.4.x
Package
Other / I don't know
Goals
Upate billing client to 5.0 or 5.1 in Facebook SDK to send properly In-app purchase events to Meta analytics console.
Expected results
In our project we already use Google Billing Client with version 5.0.
This billing client is suggested in Google Play developer console. (Should be always updated)
I want to use latest Facebook SDK with this client, but currently Facebook SDK use version 3.0.0 that can connect to Billing client in version 5.0 because of class missing.
We can't revert billing client to 4.0 because of already implemented migration from Billing client 4.0 to 5.0.
Actual results
In Facebool SDK Google client wrapper is missing class:
com.android.billingclient.api.Purchase$PurchasesResult
This class exist in billing 3.x an 4.x but on billingclient.api.Purchase in 5.0 version this is changed.
Because of that Facebook SDK can't create instance of InAppPurchaseBillingClientWrapper.
When constructor create instance, try to find class by name
com.android.billingclient.api.Purchase$PurchasesResult
and this class is missing. So wrapper is created, but instance is null.
Result of that is that SDK can't query purchases and send it automatically as events to Facebook platform.
Steps to reproduce
Use Google billing client in version 5.0 and Facebook SDK in version 16.0.1
Make in-app purchase and see that no events are sent.
No add to cart event and no purchase event.
Code samples & details
fun getOrCreateInstance(context: Context): InAppPurchaseBillingClientWrapper? {
if (initialized.get()) {
return instance
}
createInstance(context)
initialized.set(true)
return instance
}
private fun createInstance(context: Context) {
val inAppPurchaseSkuDetailsWrapper = getOrCreateInstance() ?: return
val billingClientClazz = getClass(CLASSNAME_BILLING_CLIENT)
val purchaseClazz = getClass(CLASSNAME_PURCHASE)
val purchaseResultClazz = getClass(CLASSNAME_PURCHASES_RESULT)
val skuDetailsClazz = getClass(CLASSNAME_SKU_DETAILS)
val purchaseHistoryRecordClazz = getClass(CLASSNAME_PURCHASE_HISTORY_RECORD)
val skuDetailsResponseListenerClazz = getClass(CLASSNAME_SKU_DETAILS_RESPONSE_LISTENER)
val purchaseHistoryResponseListenerClazz =
getClass(CLASSNAME_PURCHASE_HISTORY_RESPONSE_LISTENER)
if (billingClientClazz == null ||
purchaseResultClazz == null ||
purchaseClazz == null ||
skuDetailsClazz == null ||
skuDetailsResponseListenerClazz == null ||
purchaseHistoryRecordClazz == null ||
purchaseHistoryResponseListenerClazz == null) {
return
}
val queryPurchasesMethod =
getMethod(billingClientClazz, METHOD_QUERY_PURCHASES, String::class.java)
val getPurchaseListMethod = getMethod(purchaseResultClazz, METHOD_GET_PURCHASE_LIST)
val getOriginalJsonMethod = getMethod(purchaseClazz, METHOD_GET_ORIGINAL_JSON)
val getOriginalJsonSkuMethod = getMethod(skuDetailsClazz, METHOD_GET_ORIGINAL_JSON)
val getOriginalJsonPurchaseHistoryMethod =
getMethod(purchaseHistoryRecordClazz, METHOD_GET_ORIGINAL_JSON)
val querySkuDetailsAsyncMethod =
getMethod(
billingClientClazz,
METHOD_QUERY_SKU_DETAILS_ASYNC,
inAppPurchaseSkuDetailsWrapper.skuDetailsParamsClazz,
skuDetailsResponseListenerClazz)
val queryPurchaseHistoryAsyncMethod =
getMethod(
billingClientClazz,
METHOD_QUERY_PURCHASE_HISTORY_ASYNC,
String::class.java,
purchaseHistoryResponseListenerClazz)
if (queryPurchasesMethod == null ||
getPurchaseListMethod == null ||
getOriginalJsonMethod == null ||
getOriginalJsonSkuMethod == null ||
getOriginalJsonPurchaseHistoryMethod == null ||
querySkuDetailsAsyncMethod == null ||
queryPurchaseHistoryAsyncMethod == null) {
return
}
Missing class is
private const val CLASSNAME_PURCHASES_RESULT =
"com.android.billingclient.api.Purchase\$PurchasesResult"