Code: Select all
FATAL EXCEPTION: main
Process: com.brandonnathanang.retrofy, PID: 4019
java.lang.NoClassDefFoundError: Failed resolution of: Lio/ktor/client/plugins/HttpTimeout;
at io.ktor.client.engine.cio.CIOEngine.(CIOEngine.kt:25)
at io.ktor.client.engine.cio.CIO.create(CIOCommon.kt:35)
at io.ktor.client.engine.HttpClientEngineFactory$DefaultImpls.create$default(HttpClientEngineFactory.kt:82)
at com.brandonnathanang.retrofy.SupabaseClient.(SupabaseClient.kt:26)
at com.brandonnathanang.retrofy.AuthScreenKt$AuthScreen$1$1$1$1.invokeSuspend(AuthScreen.kt:59)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@624b85f, androidx.compose.runtime.BroadcastFrameClock@649a2ac, StandaloneCoroutine{Cancelling}@9f2db75, AndroidUiDispatcher@cc3470a]
Caused by: java.lang.ClassNotFoundException: Didn't find class "io.ktor.client.plugins.HttpTimeout" on path: DexPathList[[zip file "/data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/base.apk"],nativeLibraryDirectories=[/data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/lib/arm64, /data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/base.apk!/lib/arm64-v8a, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:637)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
... 18 more
Code: Select all
package com.brandonnathanang.retrofy
import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.createSupabaseClient
import io.github.jan.supabase.auth.Auth
import io.github.jan.supabase.postgrest.Postgrest
import io.github.jan.supabase.realtime.Realtime
import io.github.jan.supabase.storage.Storage
import io.ktor.client.engine.cio.CIO
object SupabaseClient {
private const val SUPABASE_URL = "https://aesfsowpmrmftctdwvyt.supabase.co"
private const val ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFlc2Zzb3dwbXJtZnRjdGR3dnl0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDQ1MDAyMjgsImV4cCI6MjA2MDA3NjIyOH0.N00hDyxxg3U4kn5ONEYtQY9iO_dw_EWyVfhTIzPrOoU"
val client: SupabaseClient = createSupabaseClient(
supabaseUrl = SUPABASE_URL,
supabaseKey = ANON_KEY
) {
install(Auth) {
scheme = "retrofy"
host = "auth/callback"
}
install(Postgrest)
install(Realtime)
install(Storage)
httpEngine = CIO.create()
}
}
Code: Select all
package com.brandonnathanang.retrofy
import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import io.github.jan.supabase.auth.auth
import io.github.jan.supabase.exceptions.RestException
import io.github.jan.supabase.postgrest.from
import io.github.jan.supabase.auth.providers.Google
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.UUID
fun Context.findActivity(): Activity? {
var currentContext = this
while (currentContext is android.content.ContextWrapper) {
if (currentContext is Activity) {
return currentContext
}
currentContext = currentContext.baseContext
}
return null
}
@Composable
fun AuthScreen(navController: NavController) {
var error by remember { mutableStateOf(null) }
var isLoading by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val activity = context.findActivity() ?: run {
error = "Activity context unavailable"
return@run
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = {
if (!isLoading) {
coroutineScope.launch {
isLoading = true
error = null
try {
Log.d("RetrofyAuth", "Starting Google Sign-In with Supabase")
SupabaseClient.client.auth.signInWith(Google)
repeat(10) {
val userId = SupabaseClient.client.auth.currentUserOrNull()?.id
if (userId != null) {
Log.d("RetrofyAuth", "Signed in user ID: $userId")
val userInfo = SupabaseClient.client.auth.currentUserOrNull()
var username = userInfo?.email?.substringBefore("@")
?: "user_${UUID.randomUUID().toString().substring(0, 8)}"
var suffix = 1
while (SupabaseClient.client.from("users")
.select { filter { eq("username", username) } }
.decodeList().isNotEmpty()) {
username = "${userInfo?.email?.substringBefore("@") ?: "user"}_$suffix"
suffix++
}
SupabaseClient.client.from("users").insert(
mapOf(
"id" to userId,
"email" to (userInfo?.email ?: ""),
"username" to username,
"favorite_decades" to emptyList()
)
)
Log.d("RetrofyAuth", "Inserted user: $username")
navController.navigate("throwback") { popUpTo("auth") { inclusive = true } }
return@launch
}
delay(1000)
}
error = "Sign-In timeout: No user detected"
Log.e("RetrofyAuth", "No user ID after polling")
} catch (e: RestException) {
error = "API error: ${e.error}"
Log.e("RetrofyAuth", "Rest error", e)
} catch (e: Exception) {
error = "Sign-In failed: ${e.message}"
Log.e("RetrofyAuth", "Unexpected error", e)
} finally {
isLoading = false
}
}
}
},
modifier = Modifier.fillMaxWidth(),
enabled = !isLoading
) {
Text(if (isLoading) "Signing in..." else "Sign in with Google")
}
if (error != null) {
Spacer(modifier = Modifier.height(8.dp))
Text(text = error ?: "", color = MaterialTheme.colorScheme.error)
}
}
}
< /code>
[b] Was ich ausprobiert habe < /strong>: < /p>
[list]
[*] Eingeschlossene Supabase- und KTOR-Abhängigkeiten in meinem Build.gradle.KTS < /code>:
implementation("io.github.jan-tennert.supabase:auth-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:postgrest-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:realtime-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:storage-kt:3.1.4")
implementation("io.ktor:ktor-client-core:2.3.7")
implementation("io.ktor:ktor-client-cio:2.3.7")
Beobachtungen [/b]:
Die Stapelspur zeigt auf cioEngine , in Übereinstimmung mit dem in Supabaseclient angegebenen CIO -Motor ist immer noch vermisst. Httptimeout Klasse ist Teil der Client -Plugins von KTOR, und ich vermute, dass es möglicherweise nicht in meinen aktuellen Abhängigkeiten enthalten ist oder dass Supabase eine bestimmte KTOR -Konfiguration benötigt. io.ktor.client.plugins.httptimeout fehlt und wie kann ich sicherstellen, dass es in meinem Projekt enthalten ist? Nichtübereinstimmung zwischen Supabase (
Code: Select all
3.1.4
Code: Select all
2.3.7