ryer.io

Debugging Token Refresh Logic in iOS and Android

TL;DR

  • Investigated token refresh behavior in iOS app, encountering multiple refresh promises due to simultaneous endpoint calls.
  • Implemented cooldown period and debated its necessity.
  • Android app faced infinite loading due to credential fetching errors, resolved some output noise; still examining undefined credential returns.

Exploring Token Refreshing in iOS

Today, I dove into testing the token refresh mechanism within my iOS application. My main objective was to observe how the app handled token refreshing when calling an endpoint. Simple enough – I started with a pull-to-refresh gesture.

Initial Observations

Upon refresh, I noticed something unexpected: multiple logs indicated the app was “waiting for existing refresh operation.” Typically, a single API call should initiate a single refresh promise. Upon further inspection, it turns out both the backlog and another service – “hills” – were called simultaneously, explaining the double logging.

As a result, the token manager logged multiple instances of waiting, and once the operations completed, it cleared the refresh promise but left a last refresh time. This means subsequent calls could initiate a cooldown period, preventing excess Auth0 calls. However, I’m questioning if this is necessary at all.

Android Infinite Loading Issue

Switching gears to Android, a peculiar issue arose: my app displayed a perpetually black screen. Logs suggested no auth token was retrieved from Auth0, though initial checks seemed to grant credentials. The token manager was error-prone, particularly when no previous credentials were set, and clunky output was complicating the logs. I cleaned it by revisiting my error handling logic.

Instead of returning unhandled errors, I considered using handleAuthError to manage them more cleanly. Yet, my app froze at “error during credential refresh,” entering a logout sequence prematurely.

Diving Deeper

The mystery deepened as error logs printed ’no previous credentials’ during initial load, implicating loadCredentials. It appeared that a failed promise or undefined payload was causing an error cascade.

Upon checking, my getOrRefreshCredentials function wasn’t yielding expected behaviors – no credentials were loaded, and auth context was presumably empty.

Conclusion So Far

Several adjustments were made, notably in error handling and output clarity. The iOS side balanced simultaneous refresh operations with a cooldown mechanic, albeit under scrutiny for necessity. Meanwhile, Android’s undefined credential returns remain a puzzle. Reproducing and dissecting this behavior is my next step, with the aim clearer logging and error definitions to untangle this loading quagmire.

Back to the drawing board with a clean console and fresh perspective!