Skip to main content
Question

Flutter Purchases.getPurchaserInfo() hangs and never returns in TestFlight

  • 21 February 2022
  • 4 replies
  • 69 views

I’m trying to push my app out for Beta testing but when I upload a build to TestFlight and run it the call to Purchases.getPurchaserInfo() hangs and never returns. It works on the same device when just running outside of TestFlight. 

I can run through the whole IAP flow when running on this device. But as soon as I push to TestFlight and run it through there it just hangs waiting to get purchaser info. 

 

I think these are the logs needed:

default    12:08:37.873277-0500    Runner    Purchases] - DEBUG: ℹ️ There are no requests currently running, starting request GET /subscribers/$RCAnonymousID0X0P+0f621ae3fbd374db9b96d0b6d31ea5d20
default    12:08:37.873327-0500    Runner    3Purchases] - DEBUG: ℹ️ API request started: GET /v1/subscribers/$RCAnonymousID:f621ae3fbd374db9b96d0b6d31ea5d20
default    12:08:37.883570-0500    Runner    Purchases] - DEBUG: ℹ️ There's a request currently running and 0 requests left in the queue, queueing GET /subscribers/$RCAnonymousID0X0P+0f621ae3fbd374db9b96d0b6d31ea5d20/offerings
default    12:08:37.944968-0500    Runner    dPurchases] - DEBUG: ℹ️ Vending PurchaserInfo from cache.
default    12:08:38.072597-0500    Runner     Purchases] - DEBUG: ℹ️ applicationDidBecomeActive
default    12:08:38.111412-0500    Runner    aPurchases] - DEBUG: ℹ️ API request completed with status: GET /v1/subscribers/$RCAnonymousID:f621ae3fbd374db9b96d0b6d31ea5d20 304
default    12:08:38.116900-0500    Runner    1Purchases] - DEBUG: ℹ️ Serial request done: GET /subscribers/$RCAnonymousID0X0P+0f621ae3fbd374db9b96d0b6d31ea5d20, 1 requests left in the queue
default    12:08:38.117369-0500    Runner    bPurchases] - DEBUG: ℹ️ Starting the next request in the queue, <RCHTTPRequest: httpMethod=GET
path=/subscribers/$RCAnonymousID0X0P+0f621ae3fbd374db9b96d0b6d31ea5d20/offerings
requestBody=(null)
headers={
    Authorization = "XXXXXX";
}
retried=0
>
default    12:08:38.154050-0500    Runner     Purchases] - DEBUG: ℹ️ API request completed with status: GET /v1/subscribers/$RCAnonymousID:f621ae3fbd374db9b96d0b6d31ea5d20/offerings 304
default    12:08:38.154144-0500    Runner    /Purchases] - DEBUG: ℹ️ Requesting products from the store with identifiers: {(
    "mylomoney_monthly_599"
)}
default    12:08:38.154505-0500    Runner    gPurchases] - DEBUG: ℹ️ Serial request done: GET /subscribers/$RCAnonymousID0X0P+0f621ae3fbd374db9b96d0b6d31ea5d20/offerings, 0 requests left in the queue
default    12:08:38.187735-0500    Runner    bPurchases] - DEBUG: ℹ️ Products request finished.
default    12:08:38.187908-0500    Runner     Retrieved SKProducts:
default    12:08:38.187958-0500    Runner    rPurchases] - DEBUG: 💰 mylomoney_monthly_599 - <SKProduct: 0x28144cf50>
default    12:08:38.188026-0500    Runner    gPurchases] - DEBUG: ℹ️ 1 completion handlers waiting on products
 

Sorry, should’ve posted in SDK’s


Hey @Mitch Dennett!

No worries about posting it in SDKs! And it seems like there is might callback that could be losing it’s reference when built for release (maybe with some optimizations). 

  1. Which version of the Flutter SDK are you using?
  2. Can you post a little snippet of how you are using `Purchases.getPurchaserInfo()`? I don’t think this should matter but I want to make sure I’m trying to replicate exactly how you are 😇

Thanks!


  Future<bool?> isPurchased() async {
try {
purchaserInfo = await Purchases.getPurchaserInfo();
if (purchaserInfo.entitlements.all["basic"]!.isActive) {
debugPrint("[mylomoney] HAS SUBSCRIPTION");
return true;
}
} on PlatformException catch (e) {
// Error fetching purchaser info
debugPrint("[mylomoney] ${e.message}");
}

showPaywall();
return null;
}

void showPaywall() {
Navigator.pushReplacementNamed(context, "/paywall");
}

@override
Widget build(BuildContext context) {
List<IconData> iconList = [
Ionicons.list,
Ionicons.card,
Ionicons.business,
Ionicons.settings,
];

return FutureBuilder<bool?>(
future: isPurchased(),
builder: (BuildContext context, AsyncSnapshot<bool?> snapshot) {
if (snapshot.hasData) {
return Scaffold(
backgroundColor: Colors.white,
bottomNavigationBar: AnimatedBottomNavigationBar(
icons: iconList,
activeIndex: pageIndex,
gapLocation: GapLocation.none,
notchSmoothness: NotchSmoothness.verySmoothEdge,
leftCornerRadius: 32,
rightCornerRadius: 32,
activeColor: CustomTheme.mint50,
onTap: (index) {
setIndex(index);
},
//other params
),
body: getBody(),
);
}

return Scaffold(
backgroundColor: Colors.white, body: Text(errorMessage));
// const Center(
// child: CircularProgressIndicator(
// valueColor: AlwaysStoppedAnimation<Color>(CustomTheme.mint50),
// ),
// );
});
}

@joshdholtz Thanks for getting back to me! Above is a small snippet on how I’m using getPurchaserInfo.

I’m using purchases_flutter: ^3.9.3


And Flutter 2.8.1.


Reply