supabase-community / supabase-kt

A Kotlin Multiplatform Client for Supabase.
https://supabase.com/docs/reference/kotlin/introduction
MIT License
405 stars 37 forks source link

[Bug]: Session Token is null when retrieved by Service #677

Closed Blickwinkel1107 closed 2 months ago

Blickwinkel1107 commented 3 months ago

General Info

Version(s)

2.5.2

Kotlin Target(s) and their respective versions

JVM8

What happened? (include your code)

I was trying to access accessToken/refreshToken in Service after user login in Activity. However the supabase client return null session. The issue varies in different phone OS. We found the issue on Harmony OS.

Steps To Reproduce (optional)

  1. Login in activity
  2. In service, when service is setting up, retrieve the session token.
    private fun setupService() {
        CoroutineScope(Dispatchers.IO).launch{
            supabase.auth.loadFromStorage()
        }
    ........
  3. Print the session, we got null
    val accessToken = supabase.auth.currentSessionOrNull()?.accessToken
    val test = supabase.auth.currentAccessTokenOrNull()
    Timber.d("accessToken is $accessToken, test is $test")
    // accessToken is null, test is null

Relevant log output (optional)

No response

jan-tennert commented 3 months ago

Two things:

Blickwinkel1107 commented 3 months ago

Hi Jan. Thanks for reply.

  1. It's in onServiceConnected() of service. Yeah it's non-blocking. I removed it btw.
  2. Is it by default loaded from storage? I loaded manually just for make sure it's loaded.

A more info about my scenario: So in my application, there's a global supabaseClient variable to be accessed by other files. And it seems when I access when service get connected (onServiceConnected) it works and doesn't need loadFromStorage However when I am emitting a network request from a composable method with Launcheffect, supabase session returns null. So it becomes:

1. I see tokens are non-null in onServiceConnected, where the whole service spins up.
2. I see tokens become null in launcheffect's http request method.

Btw, my application is a bit different, as I had some composable added to service.

jan-tennert commented 3 months ago

Is it by default loaded from storage? I loaded manually just for make sure it's loaded.

Unless disabled in the config, yes. On Android it will load depending on lifecycle events to ensure that no expired sessions get loaded. You can try out two things:

  1. Switch to your application if Auth#sessionStatus switches from LoadingFromStorage to Authenticated, NotAuthenticated, etc.. sessionStatus is a hot flow.
  2. There is also a helper function Auth#awaitInitialization() which basically does that, suspends the coroutine until the initialization is done.

The initialization is not really noticeable in terms of time usage, but making requests before that or calling currentSessionOrNull before that obviously fails.

Blickwinkel1107 commented 3 months ago

Hi Jan. When I called Auth#awaitInitialization() , application got stuck at this method. loadFromStorage works as expected. I'm not super sure if the issue relates to lifecycle management of composable views that added to windowManager.. I can find a time to have a minimum repro codes. Those Composable's lifecycleowner is set to the Service (as service has derived from LifecycleOwner)

jan-tennert commented 3 months ago

If it got stuck, the loading never appeared. The implementation for the automatic loading can be viewed here. If this is related to a lifecycle issue, then maybe manual loading will be your best bet, but then I'd disable AuthConfig#enableLifecycleCallbacks.

I can find a time to have a minimum repro codes.

If you want sure, not certain what exactly the problem is with the lifecycle.

Blickwinkel1107 commented 3 months ago

Thanks so much for your help! Will post a repro tomorrow. (PDT timezone)

Also a QQ: should I have token stored to sharedPreference? Or I can rely on loadFromStorage

jan-tennert commented 3 months ago

Also a QQ: should I have token stored to sharedPreference? Or I can rely on loadFromStorage

You can rely on loadFromStorage. You don't have to worry about saving the session at all.

jan-tennert commented 2 months ago

@Blickwinkel1107 Any update on this?

jan-tennert commented 2 months ago

Closing due to inactivity, feel free to reopen.