Skip to content

Fire promise globally before any request #376

@nandorojo

Description

@nandorojo

First off, thanks so much for this library. This is really helpful.

Problem

I am currently using the OpenAPI.TOKEN syntax to set my auth token. This works well, but it isn't perfect for my use case. The reason is that my token is accessed asynchronously.

Ideally, I could wrap the fetch function used by this lib, such that it gets my token asynchronously before every call.

I'm using Firebase auth, which 1) refreshes the token often, and 2) has an asynchronous function to get the current token.

Currently, I do this:

onAuthStateChanged(async (user) => {
  if (user) {
   // the user is set as signed in here, so I update the app's auth state
   setIsSignedIn(true) // <- this is pseudo-code. This is what Firebase does for me, for illustration.
   // thus, they're now seeing screens that require an auth token

  // it's possible to be stuck here, where the app state has updated to show authenticated screens
  // but the token promise hasn't resolved yet

   // next, I set the user's token for request
   OpenAPI.TOKEN = await user.getIdToken() 
  } else {
    OpenAPI.TOKEN = ''
  }
})

The problem with this is that await user.getIdToken() is async. Since I render authenticated screens right when user exists, then it's possible that the user will see certain screens before I have set the OpenAPI.TOKEN. This means requests that should have a token will be sent without one.

Proposed solution

At the root of my app, it would nice to be able to do something like this:

import { OpenAPI } from 'openapi-typescript-codegen'

OpenAPI.onBeforeRequest = async () => {
   OpenAPI.TOKEN = await firebase.auth().currentUser?.getIdToken() 
}

This way, before any request is sent, I know with certainty that the latest auth token is injected in my requests.

My current work-around

Currently, I have to manually call this before every request:

import { SomeService } from '../generated'

export const callServer = async () => {
   OpenAPI.TOKEN = await firebase.auth().currentUser?.getIdToken() 
   return SomeService.someCall()
}

Doing this manually isn't ideal, since I might forget some.

I'm definitely open to a better solution, and am happy to explain better if this is unclear. Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions