I'm still new to supabase so maybe I'm missing som...
# supabase-kt
c
I'm still new to supabase so maybe I'm missing something basic here... but I'm trying to implement auth via OTP and that works when I do
Copy code
supabase.auth
        .verifyEmailOtp(type = OtpType.Email.EMAIL, email = "email", token = "123456")

    val session = supabase.auth.currentSessionOrNull()

    println(session) //session is a valid object. hooray!
but then if I just restart my app and call
Copy code
val session = supabase.auth.currentSessionOrNull()
    println(session) //session is null
then i just get a null session. shouldn't my session persist?
in firebase, my session would persist in this case. i dont need to persist any auth tokens or anything. am i understanding something wrong here?
j
It does persist, but probably by the time you print out the session, it hasn't been loaded yet. (Loading is basically instant, but you can still try to access auth before) Either collect the
sessionStatus
flow and show a loading screen if the status is LoadingFromStorage/Initializing or just use
Auth#awaitInitialization()
. After that the session should be there.
c
Hm. I'm doing it via a click listener so I would expect it to be there like a second after loading the app. Let me try again!
j
Yea, also debug logs would also be helpful, as they show the loading process
c
Cool. Let me reorganize this code really quick. Its literally like 10 lines of compose + supabase code and see if I can get to the bottom of it!
Interesting. That seemed to indeed work. 152226.384 I Trying to load latest session from storage. 152226.384 I null 152226.439 I Successfully loaded session from storage! 152230.972 I UserSession(accessToken=eyJhbG...
Ah. I found the issue
Copy code
fun logSesh() {
    val session = supabase.auth.currentSessionOrNull()
    println(session)
}
is my code. and it doesn't try to load latest session from storage until I call the above method
so if i call the above method twice then I get auth
Copy code
val supabase = createSupabaseClient(
    supabaseUrl = "asdf",
    supabaseKey = "fdas"
) {
    install(Auth)
}
I thought ^ code would start my session
But I guess after I install(Auth) I should also call supabase.auth.currentSessionOrNull()
to init session
j
I thought ^ code would start my session
Well, it should.
supabase.auth.currentSessionOrNull()
is only short for
(sessionStatus as? SessionStatus.Authenticated)?.session
, so the method it self doesn't really do anything
c
interesting. i wonder why val supabase = createSupabaseClient( supabaseUrl = "asdf", supabaseKey = "fdas" ) { install(Auth) } doesn't start my session
I'm using "io.github.jan-tennert.supabasebom3.0.0-beta-1". maybe its a 3.0 bug.
j
Do you see no loading related logs without
currentSessionOrNull
?
c
Correct
So if I have already logged in. and then just delete my entire app (10 lines) I'm left with this
Copy code
val supabase = createSupabaseClient(
    supabaseUrl = "asdf",
    supabaseKey = "zxcv"
) {
    install(Auth)
    println("got here")
}

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            Supabase1Theme {
            }
        }
    }
}
which gives me these logs ---------------------------- PROCESS STARTED (16449) for package com.example.supabase1 ---------------------------- 163117.352 W A resource failed to call close. 163117.352 W A resource failed to call close. 163121.903 D Installing profile for com.example.supabase1
j
Hmm, I just created a blank project which is basically the same:
Copy code
val supabase = createSupabaseClient(
    supabaseUrl = "",
    supabaseKey = ""
) {
    defaultLogLevel = LogLevel.DEBUG //shouldn't matter as the loading logs are on the INFO level
    install(Auth)
    println("got here")
}


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
}
And I get these logs (after logging in before restart): 2024-09-20 225543.483 6829-6866 Supabase-Auth com.example.myapplication I Successfully loaded session from storage! 2024-09-20 225543.513 6829-6865 Supabase-Auth com.example.myapplication D Session found, auto refresh started
c
Soooo weird. lemme try a clean install
hm. i think maybe the creation is deffered
If I do
Copy code
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            Supabase1Theme {
                supabase
            }
        }
    }
}
then it works
i thought kotlin would create that variable right away. which now im confused why it doesn't.
Copy code
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}

android {
    namespace = "com.example.supabase1"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.supabase1"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "<http://proguard-rules.pro|proguard-rules.pro>"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
    implementation(platform("io.github.jan-tennert.supabase:bom:3.0.0-beta-1"))
    implementation("io.github.jan-tennert.supabase:auth-kt")
    implementation("io.ktor:ktor-client-cio:3.0.0-rc-1")
}
j
Okay I think Android does some weird optimization stuff. If I remove my Compose code, so that only that stays:
Copy code
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                
            }
        }
    }
}
It also appears to stop working.
c
👀
this... makes me question everything. lol
j
The session loading on Android gets triggered when the app starts via a lifecycle observer, maybe because nothing happens in the onCreate somehow these aren't getting triggered?
Weird bug, but at least we know that probably never occurs
c
Weird. I updated to
Copy code
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Supabase1Theme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Button({}) {
                        Text("Test")
                    }
                    Text("Test")
                    Text("Test")
                    Text("Test")
                    Text("Test")
                    Text("Test")
                    Text("Test")
                    Text("Test")
                    Text("Test")
                }
            }
        }
    }
}
and it still doesn't get called
j
Okay I really have no idea. That works:
Copy code
MyApplicationTheme {
    Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
        Greeting(
            name = "Android",
            modifier = Modifier.padding(innerPadding)
        )
    }
}
That doesn't:
Copy code
MyApplicationTheme {
    Text("test")
}
But calling supabase does fix it:
Copy code
MyApplicationTheme {
    val status by supabase.auth.sessionStatus.collectAsState()
    Text("test")
}
c
glad we resolved it in #C0B8MA7FA 😅 Thanks @Jan
j
Yep, no problem!