class UserAuthentication {
private val supabase = createSupabaseClient(
supabaseKey = "MySupabaseKey",
supabaseUrl = "MySupabaseUrl"
) {
install(io.github.jan.supabase.auth.Auth)
install(Postgrest)
}
private lateinit var credentialManager: CredentialManager
fun initializeCredentialManager(context: Context) {
credentialManager = CredentialManager.create(context)
val rawNonce = UUID.randomUUID().toString()
val bytes = rawNonce.toByteArray()
val messageDigest = MessageDigest.getInstance("SHA-256")
val digest = messageDigest.digest(bytes)
val hashedNonce = digest.fold("") { str, it -> str + "%02x".format(it) }
val googleIdOption: GetGoogleIdOption =
GetGoogleIdOption.Builder().setFilterByAuthorizedAccounts(false)
.setServerClientId("MyServerClientID")
.setNonce(hashedNonce).build()
val credentialRequest: GetCredentialRequest =
GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build()
GlobalScope.launch {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
try {
val result = credentialManager.getCredential(
request = credentialRequest,
context = context,
)
val credential = result.credential
val googleIdTokenCredential =
GoogleIdTokenCredential.createFrom(credential.data)
val googleIdToken = googleIdTokenCredential.idToken
supabase.auth.signInWith(IDToken) {
idToken = googleIdToken
provider = Google
nonce = rawNonce
}
// Retrieve the user_id from Supabase
val session = supabase.auth.currentSessionOrNull()
// Extract user details from credential
val email = googleIdTokenCredential.id
val userName = googleIdTokenCredential.displayName
val userId = session?.user?.id // This is the Supabase UUID
// Check if the user exists in Supabase and add if not
handleUserAuthentication(context,userId, userName, email)
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Log.d("Error initializeCredentialManager", e.message.toString())
Toast.makeText(context, "Error:-"+e.message, Toast.LENGTH_SHORT).show()
}
}
}
}
}
private suspend fun handleUserAuthentication(
context: Context,
userId: String?,
userName: String?,
email: String?
) {
if (userId == null || userName == null) {
withContext(Dispatchers.Main) {
Toast.makeText(context, "User ID or Username is missing!", Toast.LENGTH_SHORT).show()
}
return
}
try {
// Check if the user exists
val userExists = withContext(Dispatchers.IO) {
supabase.from("Table_User_Data")
.select { filter { eq("user_id", userId) } }
.decodeList()
.isNotEmpty()
}
// If user does not exist, insert a new record
if (!userExists) {
val newUser = mapOf(
"user_id" to userId,
"UserName" to userName,
"EmailID" to email,
"LatestScanDate" to null,
"LatestPurchaseTokensTimestamp" to null,
"LatestPurchaseToken" to null,
"SubscriptionActive" to false
)
val insertResult = withContext(Dispatchers.IO) {
supabase.from("Table_User_Data")
.insert(newUser) {
select() // This ensures that the inserted data is returned
}
.decodeSingle() // Decodes the result into the expected type to confirm success
}
// Notify user of successful insertion
withContext(Dispatchers.Main) {
Toast.makeText(context, "New user added successfully!", Toast.LENGTH_SHORT).show()
}
} else {
withContext(Dispatchers.Main) {
Toast.makeText(context, "User already exists!", Toast.LENGTH_SHORT).show()
}
}
} catch (e: Exception) {
// Handle exceptions
withContext(Dispatchers.Main) {
Log.d("Error handleUserAuthentication", e.message.toString())
Toast.makeText(context, "Error: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}
Дополнительный контекст:
Проект в основном написан на Java, но я использую Kotlin для конкретных случаев использования, таких как Google Credential Manager и Supabase.
Я столкнулся со следующей ошибкой: [code]Serializer for class 'Any' is not found. Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied. [/code] Я попробовал упомянутое здесь решение, но оно мне не помогло. Вот код, в котором возникает ошибка: [code]class UserAuthentication {
private lateinit var credentialManager: CredentialManager
fun initializeCredentialManager(context: Context) { credentialManager = CredentialManager.create(context)
val rawNonce = UUID.randomUUID().toString() val bytes = rawNonce.toByteArray() val messageDigest = MessageDigest.getInstance("SHA-256") val digest = messageDigest.digest(bytes) val hashedNonce = digest.fold("") { str, it -> str + "%02x".format(it) }
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder().setFilterByAuthorizedAccounts(false) .setServerClientId("MyServerClientID") .setNonce(hashedNonce).build()
val credentialRequest: GetCredentialRequest = GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build()
GlobalScope.launch { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { try { val result = credentialManager.getCredential( request = credentialRequest, context = context, ) val credential = result.credential val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data) val googleIdToken = googleIdTokenCredential.idToken
supabase.auth.signInWith(IDToken) { idToken = googleIdToken provider = Google nonce = rawNonce } // Retrieve the user_id from Supabase val session = supabase.auth.currentSessionOrNull()
// Extract user details from credential val email = googleIdTokenCredential.id val userName = googleIdTokenCredential.displayName val userId = session?.user?.id // This is the Supabase UUID
// Check if the user exists in Supabase and add if not handleUserAuthentication(context,userId, userName, email)
private suspend fun handleUserAuthentication( context: Context, userId: String?, userName: String?, email: String? ) { if (userId == null || userName == null) { withContext(Dispatchers.Main) { Toast.makeText(context, "User ID or Username is missing!", Toast.LENGTH_SHORT).show() } return }
try { // Check if the user exists val userExists = withContext(Dispatchers.IO) { supabase.from("Table_User_Data") .select { filter { eq("user_id", userId) } } .decodeList() .isNotEmpty() }
// If user does not exist, insert a new record if (!userExists) { val newUser = mapOf( "user_id" to userId, "UserName" to userName, "EmailID" to email, "LatestScanDate" to null, "LatestPurchaseTokensTimestamp" to null, "LatestPurchaseToken" to null, "SubscriptionActive" to false )
val insertResult = withContext(Dispatchers.IO) { supabase.from("Table_User_Data") .insert(newUser) { select() // This ensures that the inserted data is returned } .decodeSingle() // Decodes the result into the expected type to confirm success }
// Notify user of successful insertion withContext(Dispatchers.Main) { Toast.makeText(context, "New user added successfully!", Toast.LENGTH_SHORT).show() } } else { withContext(Dispatchers.Main) { Toast.makeText(context, "User already exists!", Toast.LENGTH_SHORT).show() } } } catch (e: Exception) { // Handle exceptions withContext(Dispatchers.Main) { Log.d("Error handleUserAuthentication", e.message.toString()) Toast.makeText(context, "Error: ${e.message}", Toast.LENGTH_SHORT).show() } } } } [/code] [b]Дополнительный контекст:[/b] [list] [*]Проект в основном написан на Java, но я использую Kotlin для конкретных случаев использования, таких как Google Credential Manager и Supabase. [/list] Есть предложения по решению этой проблемы?