stripe / stripe-terminal-react-native

React Native SDK for Stripe Terminal
https://stripe.com/docs/terminal/payments/setup-integration?terminal-sdk-platform=react-native
MIT License
95 stars 47 forks source link

discoverReaders stuck on unresolved promise #661

Open Polodiax opened 3 months ago

Polodiax commented 3 months ago

Describe the bug Hello! I'm building a multi tenant POS system using stripe-terminal-react-native and I've noticed that sometimes for reasons I'm not quite sure, the SDK will "freeze" when discovering readers.

Code console.log('discoverReadersAsync'); try { console.log('discoverReadersAsync', 100); const successCallback = success || resolve; const failureCallback = failure || reject; const onFail = () => { failureCallback(); reject(); }; const onSuccess = (s: any) => { successCallback(s); resolve(s); }; console.log('discoverReadersAsync', 200); if (retries > 3) { onFail(); return; } const {error} = await discoverReaders({ discoveryMethod: 'internet', }); console.log('discoverReadersAsync', 300); if (error) { console.log('discoverReadersAsync', 400); console.log('discoverReaders error', error); // @ts-ignore if (error.code === 'AlreadyDiscovering') { const cancelled = await cancelDiscovering(); if (!cancelled.error) { console.log('discoverReadersAsync', 410); return discoverReadersAsync( retries + 1, successCallback, failureCallback, ); } } // @ts-ignore if (error.code === 'AlreadyConnectedToReader') { await disconnectReader(); setState({ connectedReader: undefined, }); return discoverReadersAsync( retries + 1, successCallback, failureCallback, ); } onFail(); } else { console.log('discoverReadersAsync', 500); console.log('discoverReaders success'); onSuccess(''); } } catch (error) { console.log('discoverReadersAsync', 600); console.error('discoverReadersAsync error', error); }

Expected behavior I would like to be able to rediscover readers when I change the current location, and when I have the code above placed in a child component, then within the parent component I use a key based on the current location id to fully rerender the child component which hosts the discover logic, I've noticed that for the first and second time it works as expected but for subsequent rerenders it stops working. I've also noticed that when I do a metro refresh by shaking the device the same thing tends to happen a lot.

Logs Initial Render LOG discoverReadersAsync LOG discoverReadersAsync 100 LOG discoverReadersAsync 200 LOG [Stripe terminal]: didChangeOfflineStatus {"reader": undefined, "sdk": {"networkStatus": "online", "offlinePaymentAmountsByCurrency": {}, "offlinePaymentsCount": 0}} LOG currentLocation c696b073-4135-4264-a3d2-8c395f3d6c76 LOG [Stripe terminal]: didUpdateDiscoveredReaders [{"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.21.2.0", "deviceType": "wisePosE", "id": "tmr_FUcFTAN9p7jLa7", "ipAddress": "192.168.4.173", "isCharging": null, "label": "Asiamix Test", "location": {"address": [Object], "displayName": "Asiamix Test", "id": "tml_FUcEXwYKPbJnk4", "livemode": false}, "locationId": "tml_FUcEXwYKPbJnk4", "locationStatus": "set", "serialNumber": "WSC513111003272", "simulated": false, "status": "online"}, {"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.12.2.3", "deviceType": "wisePosE", "id": "tmr_FCEkRwrHIPyvTX", "ipAddress": "192.168.1.100", "isCharging": null, "label": "Honsan Test 2", "location": {"address": [Object], "displayName": "Honsan", "id": "tml_E9tU6AEB9lvmSe", "livemode": false}, "locationId": "tml_E9tU6AEB9lvmSe", "locationStatus": "set", "serialNumber": "WSC513111008085", "simulated": false, "status": "offline"}] LOG filteredReaders [{"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.21.2.0", "deviceType": "wisePosE", "id": "tmr_FUcFTAN9p7jLa7", "ipAddress": "192.168.4.173", "isCharging": null, "label": "Asiamix Test", "location": {"address": [Object], "displayName": "Asiamix Test", "id": "tml_FUcEXwYKPbJnk4", "livemode": false}, "locationId": "tml_FUcEXwYKPbJnk4", "locationStatus": "set", "serialNumber": "WSC513111003272", "simulated": false, "status": "online"}]

Complete Rerender 1 (still works) LOG currentLocation eecd886f-89a3-4a40-86ce-17f29c9cefb0 LOG currentLocation eecd886f-89a3-4a40-86ce-17f29c9cefb0 LOG currentLocation 099b7355-49a7-4f63-b814-387e1748f5c2 LOG currentLocation 099b7355-49a7-4f63-b814-387e1748f5c2 LOG initAsync LOG discoverReadersAsync LOG discoverReadersAsync 100 LOG discoverReadersAsync 200 LOG currentLocation 099b7355-49a7-4f63-b814-387e1748f5c2 LOG discoverReadersAsync 300 LOG discoverReadersAsync 400 LOG discoverReaders error {"code": "AlreadyDiscovering", "message": "Could not execute discoverReaders because the SDK is busy with another command: discoverReaders."} (here my retry logic kicks in) LOG discoverReadersAsync 410 LOG discoverReadersAsync LOG discoverReadersAsync 100 LOG discoverReadersAsync 200 LOG discoverReadersAsync 300 LOG discoverReadersAsync 400 LOG discoverReaders error {"code": "Canceled", "message": "discoverReaders was canceled."} LOG [Stripe terminal]: didFinishDiscoveringReaders {"error": {"code": "Canceled", "message": "discoverReaders was canceled."}} LOG [Stripe terminal]: didChangeOfflineStatus {"reader": {}, "sdk": {"networkStatus": "online", "offlinePaymentAmountsByCurrency": {}, "offlinePaymentsCount": 0}} LOG [Stripe terminal]: didUpdateDiscoveredReaders [{"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.21.2.0", "deviceType": "wisePosE", "id": "tmr_FUcFTAN9p7jLa7", "ipAddress": "192.168.4.173", "isCharging": null, "label": "Asiamix Test", "location": {"address": [Object], "displayName": "Asiamix Test", "id": "tml_FUcEXwYKPbJnk4", "livemode": false}, "locationId": "tml_FUcEXwYKPbJnk4", "locationStatus": "set", "serialNumber": "WSC513111003272", "simulated": false, "status": "online"}, {"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.12.2.3", "deviceType": "wisePosE", "id": "tmr_FCEkRwrHIPyvTX", "ipAddress": "192.168.1.100", "isCharging": null, "label": "Honsan Test 2", "location": {"address": [Object], "displayName": "Honsan", "id": "tml_E9tU6AEB9lvmSe", "livemode": false}, "locationId": "tml_E9tU6AEB9lvmSe", "locationStatus": "set", "serialNumber": "WSC513111008085", "simulated": false, "status": "offline"}]

Complete Rerender 2 Frozen Promise? LOG filteredReaders [{"availableUpdate": null, "batteryLevel": null, "batteryStatus": "unknown", "deviceSoftwareVersion": "2.21.2.0", "deviceType": "wisePosE", "id": "tmr_FUcFTAN9p7jLa7", "ipAddress": "192.168.4.173", "isCharging": null, "label": "Asiamix Test", "location": {"address": [Object], "displayName": "Asiamix Test", "id": "tml_FUcEXwYKPbJnk4", "livemode": false}, "locationId": "tml_FUcEXwYKPbJnk4", "locationStatus": "set", "serialNumber": "WSC513111003272", "simulated": false, "status": "online"}] LOG currentLocation c696b073-4135-4264-a3d2-8c395f3d6c76 LOG currentLocation eecd886f-89a3-4a40-86ce-17f29c9cefb0 LOG initAsync LOG discoverReadersAsync LOG discoverReadersAsync 100 LOG discoverReadersAsync 200 LOG currentLocation eecd886f-89a3-4a40-86ce-17f29c9cefb0 LOG currentLocation eecd886f-89a3-4a40-86ce-17f29c9cefb0

As you can see it is stuck on "discoverReadersAsync 200" and I don't get any errors from the discoverReaders method so I suspect it's a frozen promise. I also tried an implementation without my retry logic to ensure it was not blocking it, which it wasn't.

Stripe Terminal React Native SDK version

I'm on version 0.0.1-beta.17 with react native 0.73.1.

Smartphone (please complete the following information):

jackdewhurst commented 2 months ago

Did you ever resolve this? I'm having the same issue.

Polodiax commented 2 months ago

Nope, I'm still having this isse. Going to test if it's the same on Android as well, but right now my focus has been primarily on iOS where the issue is quite consistent.

FaggioniHQ commented 3 weeks ago

Hello There,

Any workaround on this?. It's happening on Android, iOS works fine

Polodiax commented 3 weeks ago

Haven't found a solution to this yet, unfortunately. I think the culprit is likely on the native SDK side, and the only way to reset the SDK is by completely terminating the app and then re-opening it.

FaggioniHQ commented 3 weeks ago

Hello,

i noticed that the issue begun since the last reader firmware upgrade, not sure if it's related to that.