From f1d8b9dcf46a6322966275c2a93df06d137fcf99 Mon Sep 17 00:00:00 2001 From: joni Date: Sat, 12 Oct 2024 00:33:33 +0530 Subject: [PATCH] Implemented Supabase Auth --- app/build.gradle.kts | 40 +++++++++++- app/src/main/AndroidManifest.xml | 1 + .../example/pollpulse/data/AuthRepoImpl.kt | 64 +++++++++++++++++++ .../com/example/pollpulse/ui/LoginActivity.kt | 50 +++++++++++---- .../example/pollpulse/ui/SignUpActivity.kt | 50 ++++++++++----- .../pollpulse/ui/viewmodels/AuthViewModel.kt | 46 +++++++++++++ 6 files changed, 218 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/com/example/pollpulse/data/AuthRepoImpl.kt create mode 100644 app/src/main/java/com/example/pollpulse/ui/viewmodels/AuthViewModel.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index effe00f..eebc21b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,12 +1,24 @@ +import java.util.Properties + plugins { alias(libs.plugins.android.application) alias(libs.plugins.jetbrains.kotlin.android) + kotlin("plugin.serialization") version "2.0.20" } android { namespace = "com.example.pollpulse" compileSdk = 34 + + + val key: String = com.android.build.gradle.internal.cxx.configure.gradleLocalProperties(rootDir,providers) + .getProperty("supabaseKey") + val url: String = com.android.build.gradle.internal.cxx.configure.gradleLocalProperties(rootDir,providers) + .getProperty("supabaseUrl") + + + defaultConfig { applicationId = "com.example.pollpulse" minSdk = 27 @@ -15,6 +27,9 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + buildConfigField("String", "supabaseKey", "\"$key\"") + buildConfigField("String", "supabaseUrl", "\"$url\"") } buildTypes { @@ -26,17 +41,23 @@ android { ) } } + compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } + kotlinOptions { jvmTarget = "1.8" } + buildFeatures{ +buildConfig = true + } + + } dependencies { - implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) @@ -46,6 +67,19 @@ dependencies { androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) - //PinView + // PinView implementation(libs.chaosleung.pinview) -} \ No newline at end of file + + val supabase_version = "3.0.0" + implementation("io.github.jan-tennert.supabase:postgrest-kt:$supabase_version") + implementation("io.github.jan-tennert.supabase:storage-kt:$supabase_version") + implementation("io.github.jan-tennert.supabase:auth-kt:$supabase_version") + + val ktor_version = "3.0.0-rc-1" + implementation("io.ktor:ktor-client-android:$ktor_version") + implementation("io.ktor:ktor-client-core:$ktor_version") + implementation("io.ktor:ktor-utils:$ktor_version") + + // Ensure consistent serialization version + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6c9172a..e8bb5fa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + - this.click( - view - ) - }) - } + emailEditText = findViewById(R.id.email_edt) + passwordEditText = findViewById(R.id.password_edt) + loginButton = findViewById(R.id.login) + + loginButton.setOnClickListener { + val email = emailEditText.text.toString() + val password = passwordEditText.text.toString() + + + viewModel.signIn(email, password) { success -> + if (success) { + + val intent = Intent(this, VerificationPageActivity::class.java) + startActivity(intent) + finish() + } else { - private fun click(view: View?) { - val intent = Intent( - this, - VerificationPageActivity::class.java - ) - startActivity(intent) + Toast.makeText(this, "Login failed. Please check your credentials.", Toast.LENGTH_SHORT).show() + } + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/pollpulse/ui/SignUpActivity.kt b/app/src/main/java/com/example/pollpulse/ui/SignUpActivity.kt index 1edc561..530fde8 100644 --- a/app/src/main/java/com/example/pollpulse/ui/SignUpActivity.kt +++ b/app/src/main/java/com/example/pollpulse/ui/SignUpActivity.kt @@ -2,33 +2,51 @@ package com.example.pollpulse.ui import android.content.Intent import android.os.Bundle -import android.view.View import android.widget.Button import androidx.appcompat.app.AppCompatActivity import com.example.pollpulse.R +import android.widget.EditText +import android.widget.Toast +import androidx.activity.viewModels +import com.example.pollpulse.data.AuthenticationRepositoryImpl +import com.example.pollpulse.ui.viewmodels.AuthenticationViewModel +import com.example.pollpulse.ui.viewmodels.AuthenticationViewModelFactory class SignUpActivity : AppCompatActivity() { - private lateinit var button: Button + + private lateinit var emailEditText: EditText + private lateinit var passwordEditText: EditText + private lateinit var signUpButton: Button + + + private val viewModel: AuthenticationViewModel by viewModels { + AuthenticationViewModelFactory(AuthenticationRepositoryImpl()) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_sign_up_page) + emailEditText = findViewById(R.id.email_edt) + passwordEditText = findViewById(R.id.password_edt) + signUpButton = findViewById(R.id.signin) - button = findViewById(R.id.signin) - button.setOnClickListener(View.OnClickListener { view: View? -> - this.click( - view - ) - }) - } + signUpButton.setOnClickListener { + val email = emailEditText.text.toString() + val password = passwordEditText.text.toString() + + + viewModel.signUp(email, password) { success -> + if (success) { - private fun click(view: View?) { - val intent = Intent( - this, - VerificationPageActivity::class.java - ) + val intent = Intent(this, VerificationPageActivity::class.java) + startActivity(intent) + finish() + } else { - startActivity(intent) + Toast.makeText(this, "Sign-up failed. Please try again.", Toast.LENGTH_SHORT).show() + } + } + } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/pollpulse/ui/viewmodels/AuthViewModel.kt b/app/src/main/java/com/example/pollpulse/ui/viewmodels/AuthViewModel.kt new file mode 100644 index 0000000..c84ce10 --- /dev/null +++ b/app/src/main/java/com/example/pollpulse/ui/viewmodels/AuthViewModel.kt @@ -0,0 +1,46 @@ +package com.example.pollpulse.ui.viewmodels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import com.example.pollpulse.data.AuthenticationRepositoryImpl +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + + +class AuthenticationViewModel(private val repository: AuthenticationRepositoryImpl) : ViewModel() { + + var isAuthenticated: Boolean = false + private set + + fun signIn(email: String, password: String, onResult: (Boolean) -> Unit) { + viewModelScope.launch { + val result = withContext(Dispatchers.IO) { + repository.signIn(email, password) + } + isAuthenticated = result + onResult(result) + } + } + + fun signUp(email: String, password: String, onResult: (Boolean) -> Unit) { + viewModelScope.launch { + val result = withContext(Dispatchers.IO) { + repository.signUp(email, password) + } + onResult(result) + } + } +} + + + +class AuthenticationViewModelFactory(private val repository: AuthenticationRepositoryImpl) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(AuthenticationViewModel::class.java)) { + return AuthenticationViewModel(repository) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +}