🔒
Jetpack Composeでログイン状態を維持する
🤔やってみたいこと
Jetpack Comopseで、FirebaseAuthを使用して、ログインした後ログイン状態を維持する機能を実装したい。
こちらの記事の内容を改造する
公式によると、ユーザーの情報を取得すればトークンを取得することができ、ログインの維持をするのを実現することができます。
現在ログインしているユーザーを取得するには、getCurrentUser メソッドを呼び出すことをおすすめします。ユーザーがログインしていない場合、getCurrentUser は null を返します。
val user = Firebase.auth.currentUser
if (user != null) {
// User is signed in
} else {
// No user is signed in
}
状態を管理する変数を用意して、認証状態を判定するのに使う。
var isLoggedIn by remember { mutableStateOf(FirebaseAuth.getInstance().currentUser != null) }
🚀やってみたこと
build.gradle.ktsに対応した設定をして機能実装するとログインの維持ができた。
プロジェクトレベルのbuild.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.2.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
// add firebase crashlytics
id("com.google.gms.google-services") version "4.4.1" apply false
id("com.google.firebase.crashlytics") version "2.9.9" apply false
}
Firebaseのライブラリが複数入ってますが、FirebaseAuthに関係したものだけで大丈夫です。
モジュールレベルのbuild.gradle.kts
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
}
android {
namespace = "com.junichi.yourbalance"
compileSdk = 34
defaultConfig {
applicationId = "com.junichi.yourbalance"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.13.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.9.0")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
// navigation library
val nav_version = "2.7.7"
implementation("androidx.navigation:navigation-compose:$nav_version")
// Firebase libraries
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-firestore")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-crashlytics")
}
こちらがアプリのコード
サンプルコード
package com.junichi.yourbalance
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.google.firebase.FirebaseApp
import com.google.firebase.auth.FirebaseAuth
import com.junichi.yourbalance.ui.theme.YourBalanceTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Firebaseの初期化
FirebaseApp.initializeApp(this)
setContent {
YourBalanceTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
var isLoggedIn by remember { mutableStateOf(FirebaseAuth.getInstance().currentUser != null) }
if (isLoggedIn) {
WelcomePage(onLogout = {
isLoggedIn = false
})
} else {
LoginPage(onLoginSuccess = {
isLoggedIn = true
})
}
}
}
}
}
}
@Composable
fun LoginPage(onLoginSuccess: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(onClick = { performAnonymousLogin(onLoginSuccess) }) {
Text("あなたの選択肢を選ぶ")
}
}
}
private fun performAnonymousLogin(onLoginSuccess: () -> Unit) {
FirebaseAuth.getInstance().signInAnonymously()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
onLoginSuccess()
} else {
// ログインできなかった場合の処理。今回はログを出す
println("ログインできませんでした")
}
}
}
@Composable
fun WelcomePage(onLogout: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text("ようこそ!")
Button(onClick = { onLogout() }) {
Text("ログアウト")
}
}
}
🙂最後に
今回は、Jetpack Composeで、FirebaseAuthのログインを維持する機能を実装してみました。途中でエラー連発して詰まりましたが、なんとか動くものを作れました。
気になったのは、匿名認証したユーザーのアカウントは1個しか作れなくて、もし削除するとまたアカウントを作れないようです?
Discussion