Adyen / adyen-flutter

MIT License
23 stars 7 forks source link

Google pay component sometimes causes the app to crash after minimize -> reopen #297

Open drekyyy opened 1 week ago

drekyyy commented 1 week ago

Describe the bug

The app sometimes throws a fatal exception when user comes back to the app after minimizing it for a short period of time, while on the screen that contains google pay component, or even a screen after that (one that has the gpay screen below on navigator stack). It wasnt hard to reproduce it in app's release mode (codemagic build), but when trying in debug mode on the other hand, it was close to impossible. In our case, this bug is very serious, because one of our payment methods (BLIK) requires the user to minimize the app to confirm the payment in bank app.

To Reproduce

  1. go to a screen that contains gpay component
  2. minimize the app and open some other one (the harder on ram/cpu the better, not sure)
  3. go back to the app with gpay in it
  4. crash happens:
    Fatal Exception: java.lang.IllegalStateException: Reply already submitted
       at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:35)
       at io.flutter.plugin.common.BasicMessageChannel$IncomingMessageHandler$1.reply(BasicMessageChannel.java:14)
       at ComponentPlatformInterface$Companion$setUp$4$1$1.invoke(ComponentPlatformInterface.java:31)
       at ComponentPlatformInterface$Companion$setUp$4$1$1.invoke(ComponentPlatformInterface.java:6)
       at com.adyen.checkout.flutter.components.googlepay.GooglePayComponentManager.onAvailabilityResult(GooglePayComponentManager.java:113)
       at com.adyen.checkout.googlepay.internal.provider.GooglePayComponentProvider$isAvailable$1.invoke(GooglePayComponentProvider.java:18)
       at com.adyen.checkout.googlepay.internal.provider.GooglePayComponentProvider$isAvailable$1.invoke(GooglePayComponentProvider.java:2)
       at com.adyen.checkout.googlepay.internal.provider.GooglePayComponentProvider.isAvailable$lambda$2(GooglePayComponentProvider.java:5)
       at com.google.android.gms.tasks.zzm.run(zzm.java:25)
       at android.os.Handler.handleCallback(Handler.java:958)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:230)
       at android.os.Looper.loop(Looper.java:319)
       at android.app.ActivityThread.main(ActivityThread.java:8919)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

Video I went back and forth from foreground to background, then the app crashed, and upon opening it, you are greeted by its home screen

https://github.com/user-attachments/assets/81897c37-8b47-4c07-99d1-54ad3bd4f7cf

Smartphone

App

Robert-SD commented 5 days ago

Hi @drekyyy, Very interesting finding and thank you for sharing it. I understand the significance and let’s try to resolve the issue. Based on the exception message, it seems like the method channel is being consumed already when another Google Pay availability check happens. I tried to reproduce it with the current example implementation but the issue does not occur (debug and release mode). At least on my devices or a simulator.

I see in your video that the Google Pay button disappears when leaving the app. And it seems that it is being rendered (maybe a new instance is created?) again when going back into the app. In our example app, the Google Pay component keeps its state. Maybe that could be a difference.

Would it be possible to check if multiple instances of the Google Pay component are created? Do you might have time to check our example project on your device as well? The project should work out of the box by just adding your credentials into the config file.

In the meantime, I will investigate further and check the platform channel implementation. I will adjust the example and test multiple Google Pay button instances.

https://github.com/user-attachments/assets/0bd11093-5300-4dab-bbcb-68c9eb1fd350

drekyyy commented 5 days ago

Hey @Robert-SD,

I think you are on to something, I also noticed that it was being rebuilt. I turned the widget into a const and so far the crash has not happened. I will most likely update you tomorrow whether we managed to reproduce the crash or not.

Your insight is very appreciated.