Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache and offline mode #115

Open
DennyWeinberg opened this issue Jun 9, 2023 · 1 comment
Open

Cache and offline mode #115

DennyWeinberg opened this issue Jun 9, 2023 · 1 comment

Comments

@DennyWeinberg
Copy link

Some users notify that their in app purchase state us lost when they are offline for a longer time period. Google implemented a cache which might expire early. Is there any way we implement an controlled cache in your lib, with a custom expiration time period?

Read more here: https://www.reddit.com/r/androiddev/comments/8g67wh/inapp_billing_caching/

And here: https://stackoverflow.com/questions/17154020/error-refreshing-iventory-querying-prices-of-items-response-6error

Thanks

@wgsoft-de
Copy link

If you don't need the "ProductDetails", you can easily solve it. Google caches the purchases and you can use it. In the "BillingService.kt" change the following code (comments with XXX):

    private fun processPurchases(purchasesList: List<Purchase>?, isRestore: Boolean = false) {
        if (!purchasesList.isNullOrEmpty()) {
            log("processPurchases: " + purchasesList.size + " purchase(s)")
            purchases@ for (purchase in purchasesList) {
                // The purchase is considered successful in both PURCHASED and PENDING states.
                val purchaseSuccess = purchase.purchaseState == Purchase.PurchaseState.PURCHASED
                        || purchase.purchaseState == Purchase.PurchaseState.PENDING

// XXX comment a part of this line
                if (purchaseSuccess /* && purchase.products[0].isProductReady() */) {
                    if (!isSignatureValid(purchase)) {
                        log("processPurchases. Signature is not valid for: $purchase")
                        continue@purchases
                    }

                    // Grant entitlement to the user.
                    val productDetails = productDetails[purchase.products[0]]
                    when (productDetails?.productType) {
                        BillingClient.ProductType.INAPP -> {
                            // Consume the purchase
                            when {
                                consumableKeys.contains(purchase.products[0]) -> {
                                    mBillingClient.consumeAsync(
                                        ConsumeParams.newBuilder()
                                            .setPurchaseToken(purchase.purchaseToken).build()
                                    ) { billingResult, _ ->
                                        when (billingResult.responseCode) {
                                            BillingClient.BillingResponseCode.OK -> {
                                                productOwned(getPurchaseInfo(purchase), false)
                                            }
                                            else -> {
                                                Log.d(
                                                    TAG,
                                                    "Handling consumables : Error during consumption attempt -> ${billingResult.debugMessage}"
                                                )
                                            }
                                        }
                                    }
                                }
                                else -> {
                                    productOwned(getPurchaseInfo(purchase), isRestore)
                                }
                            }
                        }
                        BillingClient.ProductType.SUBS -> {
                            subscriptionOwned(getPurchaseInfo(purchase), isRestore)
                        }
                    }

// XXX add the next 3 lines of code
                    if (productDetails == null) {
                        productOwned(getPurchaseInfo(purchase), isRestore)
                    }

                    // If the state is PURCHASED, acknowledge the purchase if it hasn't been acknowledged yet.
                    if (!purchase.isAcknowledged && purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
                        val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                            .setPurchaseToken(purchase.purchaseToken).build()
                        mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, this)
                    }
                } else {
                    Log.e(
                        TAG, "processPurchases failed. purchase: $purchase " +
                                "purchaseState: ${purchase.purchaseState} isSkuReady: ${purchase.products[0].isProductReady()}"
                    )
                }
            }
        } else {
            log("processPurchases: with no purchases")
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants