Skip to main content
Question

customerInfo.entitlements.active.isEmpty is always true

  • 16 July 2024
  • 1 reply
  • 26 views

I have an urgent production issues, where all users have access to PRO features since migrated to RevenueCat due to the following,

  1. I have an issue where customerInfo.entitlements.active.isEmpty is always returns a value when user is not subscribed. 
  2. The customerInfo.activeSubscriptions always returns the product identifier for users who have subscribed but cancelled their subscription.

I have added

                        
    print("ENTITLEMENTS \(customerInfo.entitlements)")
                            
    print("ACTIVE SUBS \(customerInfo.activeSubscriptions)")


This returns 

 

ENTITLEMENTS <RCEntitlementInfos: self.all=Tpro:],
self.active=::],self.verification=VerificationResult.notRequested>

ACTIVE SUBS e“com.appname.com.promonthly", “com.appname.com.proyearly”]


I have also tried removing cached info with  Purchases.shared.invalidateCustomerInfoCache()

 

Also when opening Debug > StoreKit, not transactions are show. 

    func verifyIAPReceipt() {
        
        Purchases.shared.invalidateCustomerInfoCache()
       
        Purchases.shared.getCustomerInfo { (customerInfo, error) in
            if error == nil {
                if let customerInfo = customerInfo {
                    
                    if customerInfo.entitlements.active.isEmpty {
                        
                        print("ENTITLEMENTS IS EMPTY") <-- This is not executed

                        self.unsubscribe()

                    } else {
                            
                            print("ENTITLEMENTS IS NOT EMPTY") <-- Executed

                        print("ENTITLEMENTS \(customerInfo.entitlements)")
                        print("ACTIVE SUBS \(customerInfo.activeSubscriptions)")
  
                        if customerInfo.activeSubscriptions.isEmpty == false {
                            print("Active Subscriptions is NOT empty") <-- Executed
                            
                            for s in customerInfo.activeSubscriptions  {
                                if s == "com.app.come.promonthly" || s == "com.app.com.proyearly"  {
                                    subscribe() <-- Executed Unlocks features
                                } 
                            }
                        } else if customerInfo.activeSubscriptions.isEmpty == true {
                            print("Active Subscriptions are empty")
                            self.unsubscribe()
                        } else {
                            print("Active Subscription and profile is subscribed")
                        }
                    }
                    
                }
                
                
            } else {
                print("ERROR GETTING CUSTOMER INFO TO VERIFY RECEIPTS")
            }
        }
    }


When using `fetchPolicy: .fetchCurrent` it is returning active subscriptions 

        Purchases.shared.getCustomerInfo(fetchPolicy: .fetchCurrent, completion: { (customerInfo, error) in
            if error != nil {
                print("FETCH POLICY ERROR:\(error)")
            }
            
            if customerInfo != nil {
                print("FETCH POLICY ACTIVE SUBSCRIPTIONS:\(customerInfo!.activeSubscriptions)")
                print("FETCH POLICY ACTIVE ENTITLEMENTS:\(customerInfo!.entitlements)")
                print("FETCH POLICY ACTIVE ALL PURCHASED PRODUCT ID'S:\(customerInfo!.allPurchasedProductIdentifiers)")
            }
        })


Output

> FETCH POLICY ACTIVE SUBSCRIPTIONS:<"com.appname.com.promonthly"]

> FETCH POLICY ACTIVE ENTITLEMENTS:<RCEntitlementInfos: self.all=(:],

> self.active=I:],self.verification=VerificationResult.notRequested>

> FETCH POLICY ACTIVE ALL PURCHASED PRODUCT
> ID'S:I"com.appname.com.promonthly"]

 

This is the subscribe code

 

    func subscribe() {
    
    print("Subscribe")

    
    //Revenue Cat
    
    if let packages = offering?.availablePackages {
        for p in packages {
            if p.storeProduct.productIdentifier == selectedproductbundle {
                                
                Purchases.shared.purchase(package: p) { (transaction, customerInfo, error, userCancelled) in
                    
                    print("PURCHASE")
                    
                    if userCancelled {
                        print("User cancelled purchase")
                        return
                    }
                    
                    if let err = error {
                        
                        if let error = error as? RevenueCat.ErrorCode {
                            print(error.errorCode)
                            print("ERROR: \(error.errorUserInfo)")
                            
                            switch error {
                            case .purchaseNotAllowedError:
                                errorDescription = "Purchases not allowed on this device."
                                showError.toggle()
                                
                            case .purchaseInvalidError:
                                errorDescription = "Purchase invalid, check payment source."
                                
                            default: break
                                
                            }
                            
                        }
                    } else if customerInfo?.activeSubscriptions.isEmpty == false {
                        print("Unlocked Pro 🎉")
                        
                        // Update profile
                        print("Customer INFO: \(customerInfo!)")
                        
                        print("Entitlements: \(customerInfo!.entitlements.all)") 
                        
                        if customerInfo != nil {
                            for s in customerInfo!.activeSubscriptions {
                                if s == "com.appname.com.promonthly" || s == "com.appname.com.proyearly"  {
                                    subscribeToPro()
                                }
                            }
                        }
                    } else {
                        print("PURCHASE WITH: \(String(describing: transaction?.productIdentifier)) && \(String(describing: customerInfo?.activeSubscriptions.count))")
                    }
                }
            }
        }
    }
    }

I have tested via simulator and on device.
 

 

Code Samples: 

https://stackoverflow.com/questions/78743165/revenuecat-checking-subscription-status-always-returns-active

 

This post has been closed for comments

1 reply

Userlevel 2
Badge +4

Hi @jaz-singh-45b9d0. It might be better to open a support ticket so we can dig into your account. Please open one up here at your convenience. 

For now, I noticed that this line

                    if customerInfo.entitlements.active.isEmpty {

print("ENTITLEMENTS IS EMPTY") <-- This is not executed

self.unsubscribe()

Should call self.subscribe(), as these are users that don’t have a subscription.

Also, we can review this in your support ticket, but can you confirm that your products are mapped to the proper entitlements? And, when you say that canceled users can still access your premium features, are they fully canceled, or did they turn off automatic renewal?

Thanks.