purchases-flutter icon indicating copy to clipboard operation
purchases-flutter copied to clipboard

Calling `login()` again crashes

Open BirjuVachhani opened this issue 5 months ago • 11 comments

‼️ Required data ‼️

Do not remove any of the steps from the template below. If a step is not applicable to your issue, please leave that step empty.

There are a lot of things that can contribute to things not working. Having a very basic understanding of your environment will help us understand your issue faster!

Environment

  • [ ] Output of flutter doctor
  • [ ] Version of purchases-flutter
  • [ ] Testing device version e.g.: iOS 15.5, Android API 30, etc.
  • [ ] How often the issue occurs- every one of your customers is impacted? Only in dev?
  • [ ] Debug logs that reproduce the issue
  • [ ] Steps to reproduce, with a description of expected vs. actual behavior Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)

Describe the bug

Cannot call login() again with a different custom app user ID. I use firebase auth for my app. When the user logs out from the app, I am not calling logout() on Purchases.When the user tries to log in with a different account, I call Purchases.login() with the new app user ID. It is throwing this error:

DEBUG( 7258): 👤 Logging in from wLuCs5qxdRcN1UJhFIsF4ef0xC02 -> oacB3yH6dnV8bq0C0v1tGwTbfO63
D/[Purchases] - DEBUG( 7258): ℹ️ No subscriber attributes to synchronize.
E/[Purchases] - ERROR( 7258): Enqueuing operation in closed dispatcher

After throwing the error, it is stuck. Nothing works. I have to kill the app and open it again.

Additional context

I am following strict Custom App user ID guidelines from the docs to avoid creating annonymous IDs.

I am on latest Flutter stable release: 3.32.6 purchases_flutter package version: 8.10.6

BirjuVachhani avatar Jul 12 '25 11:07 BirjuVachhani

👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!

RCGitBot avatar Jul 12 '25 11:07 RCGitBot

Thanks for reporting this! We will be looking into this right away 🫡

joshdholtz avatar Jul 12 '25 11:07 joshdholtz

Hello @BirjuVachhani,

I'm trying to reproduce this crash without success. Are you able to reproduce 100% of the time? Could you share the snippet of code where you call the login method? Does the app go to the background at some point during this process, or are you able to reproduce the crash by opening the app and keeping it in the foreground during the whole process?

MarkVillacampa avatar Jul 13 '25 10:07 MarkVillacampa

Yes, 100% of the time, it is happening. I have tested this on Android only. Happens on both the simulator and real device.

The app always stays in foreground.

As simple as,

  1. Call Purchases.configure with custom app user ID when user logs in ((Firebase in my case)
  2. Sign out from firebase.
  3. Sign in with a different account which triggers Purchases.login with a different custom app user ID.

BirjuVachhani avatar Jul 16 '25 12:07 BirjuVachhani

Is it possible you're calling Purchases.configure multiple times per app launch? Purchases.configure should only be called one time, and when the user logs in again you should call Purchases.login instead. That would explain the error since the Purchases instance could be recreated while there are requests pending. You can check if the library has already been configured with Purchases.isConfigured.

MarkVillacampa avatar Jul 17 '25 12:07 MarkVillacampa

Yeah, I specifically used that isConfigured check and it's not working at all like when I debug, I am pretty sure it's configure once and then checking whether it's configured or not, and then trying to call login method, but as soon as it calls the login method, it crashes.

I'll give it another shot with breakpoints to reconfirm.

BirjuVachhani avatar Jul 17 '25 12:07 BirjuVachhani

Thank you @BirjuVachhani. Let me know if it still doesn't work after you confirm that you're not calling configure multiple times. If so, it'd be great if you can isolate a the snippet of code that makes it crash so I can try to reproduce on my machine.

MarkVillacampa avatar Jul 17 '25 13:07 MarkVillacampa

I verified that Purchases.configure() is being called only once. I am properly calling Purchase.login() on next log in.

This flow works flowlessly on macOS. I am only seeing this issue on Android.

BirjuVachhani avatar Jul 20 '25 13:07 BirjuVachhani

Hi @BirjuVachhani! Are you by any chance calling Purchases.close() at any point? If so, then you do need to call Purchases.configure() again before using any of the Purchases APIs. I think that could explain why you're getting this issue and the log

E/[Purchases] - ERROR( 7258): Enqueuing operation in closed dispatcher

You should either remove the Purchases.close() call or call Purchases.configure() again after calling Purchases.close().

ajpallares avatar Jul 21 '25 07:07 ajpallares

I am not calling Purchase.close() anywhere. If that's the case, then why would it only happen on Android but not on macOS or iOS?

BirjuVachhani avatar Jul 22 '25 04:07 BirjuVachhani

If that's the case, then why would it only happen on Android but not on macOS or iOS?

The method Purchases.close() has no effect on macOS or iOS, which would explain why the issue only appears on Android.

But you're not calling this method, so let's try to find the source of the issue. I tried to reproduce the issue but I couldn't. What I did was

PurchasesConfiguration configuration = PurchasesConfiguration("my_api_key");
configuration.appUserID = "first_user_id";
await Purchases.configure(configuration);

and then, inside the app, I added a button to call RevenueCat's logIn() method with a different user ID:

await Purchases.logIn("second_user_id");

Then I see the expected logs normally

D/[Purchases] - DEBUG(19102): 👤 Logging in from first_user_id -> second_user_id
D/[Purchases] - DEBUG(19102): ℹ️ No subscriber attributes to synchronize.
D/EGL_emulation(19102): app_time_stats: avg=33.06ms min=9.66ms max=658.63ms count=42
D/TrafficStats(19102): tagSocket(83) with statsTag=0xffffffff, statsUid=-1
D/[Purchases] - DEBUG(19102): API request started: POST /subscribers/identify
...

But I get no hangs or crashes.

Could you please try some debugging experiments to see what happens in the following scenarios?

  1. What happens if you log out and then log in with the exact same user ID? Is the behavior different from logging out and then logging in with a different user ID? What are the logs previous to the hang/crash?
  2. What happens if you remove the second logIn call after the user logs out and logs in again (I know that would mean having a wrong user ID in the RevenueCat SDK, but this is just for testing purposes).
    • Does the app still hangs or crashes? What are the logs previous to the hang/crash?
    • If you call any other RevenueCat method instead of logIn() (e.g. getCustomerInfo()), does the app still hangs or crashes? What are the logs previous to the hang/crash?

Let's see if these tests help us reproduce or better understand the issue from our side 🙏

ajpallares avatar Jul 22 '25 07:07 ajpallares