Jetpack Composeでメールアドレス・パスワードログイン
Overview
Androidのネイティブアプリで、メールアドレス・パスワード認証を組み込むのをやってみました。今回は、画面遷移のパッケージも必要みたいで、Firebase Auth
とnavigation-compose
を使っています。
画面遷移のパッケージ
メールアドレス・パスワードでのログインのやり方
ログインとアカウント作成をするメソッド
公式のものをそのまま記載
新規のユーザー作成
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "createUserWithEmail:success")
val user = auth.currentUser
updateUI(user)
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.exception)
Toast.makeText(
baseContext,
"Authentication failed.",
Toast.LENGTH_SHORT,
).show()
updateUI(null)
}
}
ログイン
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithEmail:success")
val user = auth.currentUser
updateUI(user)
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.exception)
Toast.makeText(
baseContext,
"Authentication failed.",
Toast.LENGTH_SHORT,
).show()
updateUI(null)
}
}
こちらを参考に、認証機能を作ってみました。
summary
まずは、build.gradleの設定をしてください。こちらの記事と設定方法は同じです。今回は、画面遷移のパッケージを追加しただけですね。
上の方のbuild.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.0.2' apply false
id 'com.android.library' version '8.0.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
id("com.google.gms.google-services") version "4.4.0" apply false// Firebaseのコードを追加
}
下の方のの方のbuild.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id("com.google.gms.google-services")
}
android {
namespace 'com.example.firebaseauthapp'
compileSdk 34
defaultConfig {
applicationId "com.example.firebaseauthapp"
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled 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.3.2'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.5.1'
implementation platform('androidx.compose:compose-bom:2022.10.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:2022.10.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
// 画面遷移のパッケージを追加する
def nav_version = "2.7.1"
implementation "androidx.navigation:navigation-compose:$nav_version"
// Firebase Authのパッケージ追加
implementation platform('com.google.firebase:firebase-bom:31.0.0')
implementation("com.google.firebase:firebase-auth-ktx")
}
最初は、同じファイルにコードをまとめていたのですが、コードの量が多すぎて見づらいので別ファイルに分けました。
こちらが最初に表示されるページです。新規登録のボタンを押すと、画面遷移して新規登録のページへ移動します。
ログインページ
package com.example.firebaseauthapp.view
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.height
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
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 androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LoginPage(navController: NavController) {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("メールアドレス") }
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("パスワード") }
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { performLogin(email, password, navController) }) {
Text("ログイン")
}
Button(onClick = { navController.navigate("signup") }) {
Text("新規登録はこちら")
}
}
}
private fun performLogin(email: String, password: String, navController: NavController) {
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// ログイン成功、ホーム画面に遷移
navController.navigate("home")
} else {
// エラーハンドリング
}
}
}
新規作成のページでアカウントがない人は新しく作成します。ログインページへ戻れるように、AppBarを配置して、バックボタンもつけました。
新規作成ページ
package com.example.firebaseauthapp.view
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.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
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 androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignUpPage(navController: NavController) {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Scaffold(
topBar = {
TopAppBar(title = { Text("新規登録") },
navigationIcon = {
IconButton(onClick = { navController.navigateUp() }) {
Icon(Icons.Filled.ArrowBack, contentDescription = "戻る")
}
}
)
}
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(it)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("メールアドレス") }
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("パスワード") }
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { performSignUp(email, password, navController) }) {
Text("新規登録")
}
}
}
}
private fun performSignUp(email: String, password: String, navController: NavController) {
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// 登録成功、ログイン画面に遷移
navController.navigate("login")
} else {
// エラーハンドリング
}
}
}
ログインしたら表示されるページには、ユーザーのメールアドレス表示を表示するテキストと、ログアウトボタンを配置してます。
ログイン後のページ
package com.example.firebaseauthapp.view
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.height
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.firebase.auth.FirebaseAuth
@Composable
fun HomePage(navController: NavController) {
val user = FirebaseAuth.getInstance().currentUser
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "ようこそ、${user?.email ?: "ゲスト"}さん!")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { performLogout(navController) }) {
Text("ログアウト")
}
}
}
private fun performLogout(navController: NavController) {
FirebaseAuth.getInstance().signOut()
navController.navigate("login")
}
アプリを実行するMainActivity.kt
には、画面遷移のルートの定義してます。
アプリを実行するファイル
package com.example.firebaseauthapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.firebaseauthapp.ui.theme.FirebaseAuthAppTheme
import com.example.firebaseauthapp.view.HomePage
import com.example.firebaseauthapp.view.LoginPage
import com.example.firebaseauthapp.view.SignUpPage
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FirebaseAuthAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
FirebaseAuthAppTheme {
val navController = rememberNavController()
// 最初に表示するページをstartDestinationで指定
NavHost(navController = navController, startDestination = "login") {
composable("login") { LoginPage(navController) }
composable("signup") { SignUpPage(navController) }
composable("home") { HomePage(navController) }
}
}
}
}
}
}
}
🚗画面遷移はこんな感じです
ログイン前
新規登録
ログイン後
thoughts
いかがでしたでしょうか?
今回は、Androidのネイティブアプリにメールアドレス・パスワード認証を組み込んでみました。新規登録のページも必要なので、画面遷移のパッケージも今回導入してます。
画面遷移のやり方を紹介した記事
補足情報
build.gradle
で、compileOptions
とkotlinOptions
を11にしておくと、良いとAndroidに詳しい方から教わりました!
こんな感じ! ビルドは通る
compileOptions {
sourceCompatibility JavaVersion.VERSION_11// 1.8から11に変更
targetCompatibility JavaVersion.VERSION_11// 1.8から11に変更
}
kotlinOptions {
jvmTarget = '11'// 1.8から11に変更
}
Discussion