jorgefspereira / plaid_flutter

Plaid Link for Flutter. Integrates the native iOS, Android and Web SDKs.
https://pub.dev/packages/plaid_flutter
MIT License
67 stars 44 forks source link

Stream Events returning multiple times #100

Closed kupresk14 closed 6 months ago

kupresk14 commented 1 year ago

Hello all,

We are running Flutter version 3.7.12 with plaid_flutter version 3.1.1 and we are running into the following issue:

We've noticed that our onExit and onSuccess functions are being triggered multiple times in a row on a continual basis. Not good when trying to handle the returning events.

I took a look at the PlaidLink class and it appears that the Event streams are returning the same values multiple times in a row.

If you add a breakpoint to the .where call on the object you will notice that it is returning instances of LinkExit (if adding a breakpoint to the LinkExit stream) multiple times. The same is also occurring with the LinkEvent and LinkSuccess streams.

https://github.com/jorgefspereira/plaid_flutter/blob/5e00cc76c2d25b1c84e66f5d9c2d978afdcfa8da/lib/src/core/plaid_link.dart#L32

It does not appear that any data within the event objects are being changed between these multiple instances. Is it possible that a .firstWhere should be used here instead?

If there is a bigger issue with the stream I did not go past that. Wanted to see if anyone else is noticing this as well. Let me know if there is anything else I can provide here. This is my first issue opened so I apologize if the format is incorrect.

jorgefspereira commented 1 year ago

Hi @kupresk14,

I tried to replicate with the provided example of this plugin...but no success.

Can you share more details about your implementation? and you link token creation params?

kupresk14 commented 1 year ago

Hi @jorgefspereira, thanks for the response!

Our app is using GetX for state management, the VM housing the plaid code is extending a GetxController with a WidgetsBindingObserver. That observer is just being used for app resume / pause / screen detachment.

I will say, we have noticed that this is only happening if the user has already used Plaid Link succesfully and then goes in a second time to try linking a new bank. Honestly it really may be something messed up on our end.

Here's what our LegacyLinkConfiguration looks like. We are using this to specifically grab a user's checking account if they have one.

LegacyLinkConfiguration(
      clientName: appName,
      publicKey: plaidToken,
      environment: plaidEnvironment,
      webhook: plaidWebhook,
      products: <LinkProduct>[LinkProduct.auth, LinkProduct.transactions],
      language: 'en',
      accountSubtypes: <LinkAccountSubtype>[LinkAccountSubtypeDepository.checking],
      token: plaidLinkToken,
      countryCodes: <String>['US'],
      oauthConfiguration: LinkOAuthConfiguration(),
      userLegalName: '${userModel.firstName ?? ''} ${userModel.lastName ?? ''}',
      userEmailAddress: userModel.email ?? '',
      userPhoneNumber: userModel.phoneNumber ?? '',
    );

We are following the typical example and have each event set up with a callback. These do work but as mentioned the callbacks themselves are being triggered multiple times.

PlaidLink.onEvent.listen(_onEventCallback);
PlaidLink.onExit.listen(_onExitCallback);
PlaidLink.onSuccess.listen(_onSuccessCallback);

If this isn't replicable I'll just close this issue. I appreciate you taking a look!

lzapar2 commented 12 months ago

@kupresk14 @jorgefspereira I am experiencing the same issue, having just performed an upgrade of the sdk. All types of events are duplicated (onEvent, onExit, onSuccess). We moved up from 2.2.2 which did not have this problem.

I'm on: Flutter 3.7.9 plaid_flutter version 3.1.1

This is the request we send to create link tokens:

{
  "user": {
    "clientUserId": "1234",
    "legalName": "Joe Smith",
    "emailAddress": "jsmith@test.com"
  },
  "clientName": "test",
  "products": [
    "transactions"
  ],
  "countryCodes": [
    "US"
  ],
  "language": "en",
  "webhook": "https://www.domain.com/webhooks",
  "redirectUri": "https://www.domain.com/return/oauth"
}
jorgefspereira commented 12 months ago

Thanks @lzapar2. I'll revaluate this issue. Can you replicate on the example provided by this repository?

lzapar2 commented 11 months ago

I'm going to try some time this week. We band-aided it for now on our end by manually de-duping the events and unsubscribing from the streams when link is closed.

Something that maybe is contributing to this issue: we utilize the sdk inside of VM class that gets instantiated when a modal bottom sheet is opened. Perhaps the VM instance gets duplicated somehow on different opens of the bottom sheet and that's what's causing it. Still, this was not an issue on older versions of the sdk, so our behavior may just be exposing some edge case with the subscriptions.

leedagr8 commented 11 months ago

This is currently happening to me in my app as well. @lzapar2 can you provide a screen shot of how you were able to de-duplicate the events?

jasonmcaffee commented 11 months ago

The PlaidLink now returns a Stream. You must maintain a reference to the returned subscription and cancel it when your widget/page unloads.

final eventSubscription = PlaidLink.onEvent.listen(handleFunction)

…

subscription.cancel()
lzapar2 commented 8 months ago

What Jason posted above is correct. The stream needed to be cleaned up when exiting the flow. It's not immediately obvious when looking at the docs and we missed it in our 2.x to 3.x upgrade, although there is an example showing how to unsubscribe in the repository: https://github.com/jorgefspereira/plaid_flutter/blob/1857c32138069b29d39a110a295e422d412eff1d/example/lib/main.dart#L30