Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x1fbabb5b0
Version of flutter_inapp_purchase
flutter_inapp_purchase: ^5.6.1
Platforms you faced the error (IOS or Android or both?)
IOS
Expected behavior
Ran this code:
try {
await FlutterInappPurchase.instance.requestPurchase(
state.selectedProduct!.productId!,
);
} catch (e, s) {
AppLogger.error(e.toString(), stackTrace: s);
} finally {
emit(state.copyWith(isBuying: false));
}
Actual behavior
The app crashes, I couldn't catch
Error information:
NSInvalidArgumentException: -[NSNull length]: unrecognized selector sent to instance 0x1fbabb5b0
0 CoreFoundation +0x2d5e8 ___exceptionPreprocess
1 libobjc.A.dylib +0x31240 _objc_exception_throw
2 CoreFoundation +0x186170 -[NSObject(NSObject) doesNotRecognizeSelector:]
3 CoreFoundation +0x305b4 ____forwarding___
4 CoreFoundation +0x2fedc ___forwarding_prep_0___
5 Foundation +0x19d1c static String._unconditionallyBridgeFromObjectiveC(_:)
6 StoreKit +0x78d9c 0x1b00bfd9c (0x1b00bfd64 + 56)
7 StoreKit +0x764e0 0x1b00bd4e0 (0x1b00bd1c0 + 800)
8 StoreKit +0x7583c 0x1b00bc83c (0x1b00bc280 + 1468)
9 StoreKit +0x75088 0x1b00bc088 (0x1b00bc00c + 124)
10 StoreKit +0x7764a 0x1b00be64a (0x1b00be58c + 190)
11 StoreKit +0x79862 0x1b00c0862 (0x1b00c0860 + 2)
12 StoreKit +0x52b72 0x1b0099b72 (0x1b0099b70 + 2)
13 StoreKit +0x52b72 0x1b0099b72 (0x1b0099b70 + 2)
14 StoreKit +0x52b72 0x1b0099b72 (0x1b0099b70 + 2)
15 StoreKit +0x4e05a 0x1b009505a (0x1b0094fa8 + 178)
16 StoreKit +0x4e1ae 0x1b00951ae (0x1b009511c + 146)
17 StoreKit +0x4e05a 0x1b009505a (0x1b0094fa8 + 178)
18 libswift_Concurrency.dylib +0x69e36 completeTask(swift::AsyncContext*, swift::SwiftError*)
App info:
Process Data:
- Name: Runner
- Version: 1.0.6
- Version Code: 2
- Platform: iOS
- Release Stage: Production
Memory:
- Free Memory: 3.2 GB
- Memory Usage: 292.6 MB
- Memory Limit: 3.5 GB
Duration:
- Total Duration: 3.49 seconds
- Foreground Duration: 3.49 seconds
- Process State:
Device: Device Information:
- Manufacturer: Apple
- Model: iPhone 15 Pro Max (iPhone16,2)
- Model Number: D84AP
- Locale: en_US
- Orientation: Portrait
- Operating System (OS): iOS
- OS Version: 18.2
- Runtime Versions:
- Clang Version: 15.0.0 (clang-1500.3.9.4)
- OS Build: 22C5142a
- Simulator: No
- Jailbroken: No
- Thermal State: Nominal
Battery:
- Battery Level: 55%
- Charging: No
Memory:
- Free Memory: 200.4 MB
- Total Memory: 8.0 GB
- Word Size: 64-bit
Timestamp:
- Time: 2024-12-04T21:37:22.421Z
- Timezone: EST
Tested environment (Emulator? Real Device?)
Only in production, is in just one user. That happened after he open the app and try to buy a subscription after download. And the user tried another 4 times and had the same error
Steps to reproduce the behavior
I couldn't, do you know where could be the error here? Thank you
I'm running into the same issue within my app and have traced the problem to the following (I believe only impacting users on iOS 18.2):
obfuscatedAccountId is null, but placing a string here will prevent the crash.
Does anybody know if putting a random string here will impact restore purchase later on?
return await _channel.invokeMethod('buyProduct', <String, dynamic>{
'sku': productId,
'forUser': obfuscatedAccountId ?? "NEED_STRING_HERE_TO_PREVENT_CRASH",
});
I'm facing the same issue. Has anyone found a solution?
this issue happen only on IOS 18.2 ( it doesn't appear on previous version like IOS 18.1 ) , is there any up coming fix ?
We are currently facing this issue as well only on 18.2. Any planned fix ??
This issue occurs on devices running iOS 18.2 when calling FlutterInappPurchase.instance.requestPurchase without providing the obfuscatedAccountId parameter. This parameter corresponds to the applicationUsername field in SKMutablePayment. It is primarily used to identify the user during server-side purchase validation. When validating the purchase, Apple includes the applicationUsername value as part of the validated receipt.
You can safely assign a unique value, a placeholder, or simply an empty string ("") if user identification is not required for validation.
Fix:
To resolve the issue, pass an empty obfuscatedAccountId when calling the function:
FlutterInappPurchase.instance.requestPurchase(productId, obfuscatedAccountId: "");
Closes since 6.0.0.rc-x has been released!