'Firebase authentication - refreshToken automatic refresh

I am developing a react-native application which will use firebase authentication, and I have some doubts about how refresh tokens should work. I am using the react native package https://rnfirebase.io/ "@react-native-firebase/auth": "^14.9.0" and so far everything works great (login/account-creation, password reset flow, etc)

However, I have doubts about how the idToken should be refreshed.
From the documentation, and several posts (post1, post2 with similar issue, post3, etc), my understanding is that the react native package uses the android & ios SDK which should be managing token refreshes for me and dispatching the onIdTokenChanged event when the idToken expires and is refreshed. I read that the idToken expires in 1h, so I would expect the token to be refreshed every hour.

In practice however I don't see this behavior.
Here is a minimal reprod of what I set up in app with logging when the onIdTokenChanged event is dispatched, and when the idToken actually expires

const [ user, setUser ] = useState(null)

// Listens to onIdTokenChanged
useEffect(() => {
  auth().onIdTokenChanged((_user) => {
    console.log('auth//test//onIdTokenChanged')
    setUser(_user)
  })
}, [])

// Sets a timer on idToken expiry
useEffect(() => {
  if (!user) {
    return
  }

  (async function () {
    const idTokenResult = await user.getIdTokenResult()
    const expirationDate = new Date(idTokenResult.expirationTime)
    const expiresIn = expirationDate.getTime() - Date.now()
    console.log(`auth//test//tokenWillExpireIn:${expiresIn / 60000}min`)

    setTimeout(() => {
      console.log('auth//test//tokenExpired')
    }, expiresIn)
  })()
}, [ user ])


And here are the resulting logs after login:

2022-05-13T09:47:05.156Z: auth//test//onIdTokenChanged
2022-05-13T09:47:05.238Z: auth//test//onIdTokenChanged
2022-05-13T09:47:05.274Z: auth//test//tokenWillExpireIn:59.09545min
2022-05-13T09:47:05.358Z: auth//test//tokenWillExpireIn:59.094033333333336min
2022-05-13T10:46:11.015Z: auth//test//tokenExpired
2022-05-13T10:46:11.018Z: auth//test//tokenExpired
END

Result is: onIdTokenChanged is dispatched on app start twice, then an hour later the token expires, but why is the onIdTokenChanged not dispatched again when the token expires ?

Am I setting up something incorrectly/did I misunderstand the documentation?

Thanks in advance for your help!

EDIT
After some more research it seems the onIdTokenChanged event is dispatched lazily, as in only when you invoke getIdToken() and it sees the token should be refreshed. I read this behavior in an issue in the js sdk, and seems to be indicated in this post when reading between the lines.
I did some testing, and indeed it seems to be the case

Can someone confirm this whether these onIdTokenChanged/onAuthStateChanged events are triggered lazily? The documentation doesn't seem clear about this



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source