JackAppDev / flutter_iap

Flutter iap plugin
MIT License
100 stars 15 forks source link

Can't get it working - Error: null object reference #16

Closed evanave closed 6 years ago

evanave commented 6 years ago

Is anyone else getting this error? I have it working on iOS - just an issue on Android.

D/BillingManager( 7482): Creating Billing client. D/BillingManager( 7482): Starting setup. E/MethodChannel#flutter_iap( 7482): Failed to handle method call E/MethodChannel#flutter_iap( 7482): java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference E/MethodChannel#flutter_iap( 7482): at com.jackappdev.flutteriap.FlutterIapPlugin$3.onSkuDetailsResponse(FlutterIapPlugin.java:110) E/MethodChannel#flutter_iap( 7482): at com.android.billingclient.api.BillingClientImpl.querySkuDetailsAsync(BillingClientImpl.java:404) E/MethodChannel#flutter_iap( 7482): at com.jackappdev.flutteriap.BillingManager.querySKUProducts(BillingManager.java:287) E/MethodChannel#flutter_iap( 7482): at com.jackappdev.flutteriap.FlutterIapPlugin.onMethodCall(FlutterIapPlugin.java:126) E/MethodChannel#flutter_iap( 7482): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:191) E/MethodChannel#flutter_iap( 7482): at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:136) E/MethodChannel#flutter_iap( 7482): at android.os.MessageQueue.nativePollOnce(Native Method) E/MethodChannel#flutter_iap( 7482): at android.os.MessageQueue.next(MessageQueue.java:325) E/MethodChannel#flutter_iap( 7482): at android.os.Looper.loop(Looper.java:142) E/MethodChannel#flutter_iap( 7482): at android.app.ActivityThread.main(ActivityThread.java:6938) E/MethodChannel#flutter_iap( 7482): at java.lang.reflect.Method.invoke(Native Method) E/MethodChannel#flutter_iap( 7482): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) E/MethodChannel#flutter_iap( 7482): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) E/flutter ( 7482): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception: E/flutter ( 7482): PlatformException(error, Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference, null) E/flutter ( 7482): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:547:7) E/flutter ( 7482): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18) E/flutter ( 7482): <asynchronous suspension> E/flutter ( 7482): #2 FlutterIap.fetchProducts (package:flutter_iap/flutter_iap.dart:10:36) E/flutter ( 7482): <asynchronous suspension> E/flutter ( 7482): #3 PurchasePageState.init (package:flutter_app/video_test.dart:19:45) E/flutter ( 7482): <asynchronous suspension> E/flutter ( 7482): #4 PurchasePageState.initState (package:flutter_app/video_test.dart:14:5) E/flutter ( 7482): #5 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3751:58) E/flutter ( 7482): #6 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5) E/flutter ( 7482): #7 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #8 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #9 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14) E/flutter ( 7482): #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16) E/flutter ( 7482): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5) E/flutter ( 7482): #14 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5) E/flutter ( 7482): #15 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5) E/flutter ( 7482): #16 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #17 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #18 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14) E/flutter ( 7482): #19 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #20 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #21 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14) E/flutter ( 7482): #22 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #23 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #24 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14) E/flutter ( 7482): #25 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #26 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #27 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14) E/flutter ( 7482): #28 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #29 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #30 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16) E/flutter ( 7482): #31 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5) E/flutter ( 7482): #32 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5) E/flutter ( 7482): #33 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3769:11) E/flutter ( 7482): #34 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5) E/flutter ( 7482): #35 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #36 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #37 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16) E/flutter ( 7482): #38 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5) E/flutter ( 7482): #39 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5) E/flutter ( 7482): #40 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5) E/flutter ( 7482): #41 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14) E/flutter ( 7482): #42 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12) E/flutter ( 7482): #43 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16 D/BillingManager( 7482): Setup finished. Response code: 0 D/AndroidRuntime( 7482): Shutting down VM E/AndroidRuntime( 7482): FATAL EXCEPTION: main E/AndroidRuntime( 7482): Process: com.winogradapps.flutterapp, PID: 7482 E/AndroidRuntime( 7482): java.lang.NullPointerException: Attempt to invoke interface method 'void com.jackappdev.flutteriap.BillingManager$BillingUpdatesListener.onBillingClientSetupFinished()' on a null object reference E/AndroidRuntime( 7482): at com.jackappdev.flutteriap.BillingManager$1.run(BillingManager.java:101) E/AndroidRuntime( 7482): at com.jackappdev.flutteriap.BillingManager$7.onBillingSetupFinished(BillingManager.java:340) E/AndroidRuntime( 7482): at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection.onServiceConnected(BillingClientImpl.java:887) E/AndroidRuntime( 7482): at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1658) E/AndroidRuntime( 7482): at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1687) E/AndroidRuntime( 7482): at android.os.Handler.handleCallback(Handler.java:789) E/AndroidRuntime( 7482): at android.os.Handler.dispatchMessage(Handler.java:98) E/AndroidRuntime( 7482): at android.os.Looper.loop(Looper.java:164) E/AndroidRuntime( 7482): at android.app.ActivityThread.main(ActivityThread.java:6938) E/AndroidRuntime( 7482): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 7482): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) E/AndroidRuntime( 7482): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

alamboley commented 6 years ago

Hi @evanave I've exactly the same issue.

wupshaw commented 6 years ago

Same issue - Android not working.

JackAppDev commented 6 years ago

Does this issue happen on the example when you configure it?

evanave commented 6 years ago

Same error when I run flutter_iap out of the box. What should I configure before trying it again?

JackAppDev commented 6 years ago

You would have to set it up with google play console by linking the bundle identifier and adding permissions/enabling and whatnot. Also, google doesn't allow testing in app billing on emulators so you would need a physical device. here's the docs https://developer.android.com/google/play/billing/billing_overview

evanave commented 6 years ago

I'm testing on a live android device:

Manifest:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="com.android.vending.BILLING" />

And bundle ID does match.

I believe all of those are taken care of. Perhaps it's still loading something when it tries the next step?

JackAppDev commented 6 years ago

Looks like I provided a faulty example. Refer to this:

if (defaultTargetPlatform == TargetPlatform.iOS) {
  // use FlutterIap.fetchProducts
} else {
  // just use the ids you would normally pass to FlutterIap.fetchProducts
}

Basically, Android doesn't need to use the fetchProducts method.

evanave commented 6 years ago

So does it just get the pricing when you try to purchase with a string as a productId?

evanave commented 6 years ago

That did the trick!

So it looks like Android needs to be hard-coded (unless the reference below is implemented), whereas iOS can retrieve the data and then fill in.

Looks like on the Android side, it would need to use mService.getSkuDetails. https://stackoverflow.com/questions/5533676/android-in-app-billing-item-price

But for simple implementation, one could just keep the price hard-coded into the app with the current state of the plugin.

Here is my working code:

   if(Platform.isAndroid) {
      print("Is Android");
      productList = ["permanent_pro_license"];
    } else {
      IAPResponse response = await FlutterIap.fetchProducts(["calc0002"]);
      List<IAPProduct> productIds = response.products;
      print("Trying to fetch ${productIds.toString()}");
      setState(() {
        _productIds = productIds;
      });
    }

I can then do a

  void purchaseAndroid() {
    FlutterIap.buy("permanent_pro_license");
  }

and it works!