ticketmaster / Android-TicketsDemoApp

Android Ignite/Ticketmaster SDK, Tickets framework demo integration
MIT License
2 stars 0 forks source link

Error opening checkout when using Purchase as a Fragment instead of an Activity #6

Closed ohsnapitscolin closed 10 months ago

ohsnapitscolin commented 1 year ago

Hey all,

I filed an issue in the React Native demo repo as well, but essentially I'm trying to create a Purchase Fragment using the example code here. The problem is the app crashes with the following error when trying to open checkout:

E/DevLauncher: DevLauncher tries to handle uncaught exception.
    com.ticketmaster.purchase.exception.TMFragmentFactoryNotFound: Please use TMPurchaseFragmentFactory
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseFragment$setupNavigationObserver$1.invoke(PurchaseFragment.kt:319)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseFragment$setupNavigationObserver$1.invoke(PurchaseFragment.kt:298)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseFragment$sam$androidx_lifecycle_Observer$0.onChanged(Unknown Source:2)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseViewModel.openCheckout(PurchaseViewModel.kt:469)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseViewModel.setAccessToken(PurchaseViewModel.kt:408)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseViewModel.access$setAccessToken(PurchaseViewModel.kt:63)
        at com.ticketmaster.purchase.internal.ui.ticket.PurchaseViewModel$shouldHandleUrl$handleUrlForCheckout$1$1.invokeSuspend(PurchaseViewModel.kt:371)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
        Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@88d29d1, Dispatchers.Main.immediate]

It looks like in the Fragment demo code, we use the childFragmentManager instead of the supportFragmentManager that's used in this activity-based demo (which I believe is necessary, since we're creating a PurchaseFragment, not a PurchaseActivity).

val factory = TMPurchaseFragmentFactory(
    tmPurchaseNavigationListener = PurchaseNavigationListener {
        childFragmentManager.popBackStack()
    }
).apply {
    childFragmentManager.fragmentFactory = this
}

The problem seems to be the following lines in com.ticketmaster.purchase.internal.ui.ticket.PurchaseFragment$setupNavigationObserver$1 (which I when I dug into them look something like this):

PurchaseFragment var3 = this.this$0;
int var5 = false;
FragmentFactory var6 = var3.requireActivity().getSupportFragmentManager().getFragmentFactory();
TMPurchaseFragmentFactory fragmentFactory = var6 instanceof TMPurchaseFragmentFactory ? (TMPurchaseFragmentFactory)var6 : null;
if (fragmentFactory == null) {
   throw new TMFragmentFactoryNotFound("Please use TMPurchaseFragmentFactory");
}

In this case the requireActivity().getSupportFragmentManager().getFragmentFactory() is not a TMPurchaseFragmentFactory, because the factory was set on the childFragmentManager instead.

Is it possible to support the Fragment use case? Or do I need to use a separate activity entirely? Is is possible to pull the childrenFragmentManager from the PurchaseFragment in the code above?

TakaGoto commented 12 months ago

@ohsnapitscolin i found a solution for this, i explicitly set the parents fragment factory along with the child fragment. https://github.com/ticketmaster/ReactNative-TicketmasterDemoIntegration/pull/10

ohsnapitscolin commented 10 months ago

Closing this since there's a discussion happening on the issue mentioned above.