はじめに
最近jetpack composeでFirebaseを始めたんですが、なかなか日本語の記事がヒットしなかったり、構造複雑すぎじゃね!?とかが多かったので今回はFirebase初学者向けに簡単に実装できて色々と応用が効くように実装したいと思います。
参考資料
英語の動画ですがコードだけ参考にする程度であれば字幕つけるだけで十分に理解出来ます。
こちらはFirebaseAuthを使う際に構造を理解するために使いました。
丸々コピペより構造を理解しながら使うのがベストかも、、、
実装
1.Android Studioを立ち上げたら、Macだったら上部の(Windowsであったら左上の三本線を押して上部の)toolsからFirebaseを選択します。
2.したらAuthenticatonを選択して①のConneConnect your app to Firebaseを完了させて下さい。
困ったらこちらを参考にしたら間違い無いです!
https://firebase.google.com/docs/android/setup?hl=ja
3.そしたらProjectレベルのbuild.gradle.ktxに下記が追加されているか確認して下さい
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.jetbrains.kotlin.android) apply false
id("com.google.gms.google-services") version "4.4.2" apply false
}
4.Moduleレベルのbuild.gradle.ktxに追加して下さい
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("com.google.gms.google-services")
}
/*,,,,*/
dependencies {
/*,,,,*/
//navigation
implementation("androidx.navigation:navigation-compose:2.7.7")
//coil
implementation("io.coil-kt:coil-compose:2.4.0")
// Firebase
implementation(platform("com.google.firebase:firebase-bom:33.1.1"))
implementation("com.google.firebase:firebase-analytics")
// toolsのFirebaseからAuthenticationの②から自動で追加されます。
implementation(libs.firebase.auth)
// Credential Manager
implementation ("androidx.credentials:credentials:1.2.2")
implementation ("androidx.credentials:credentials-play-services-auth:1.2.2")
implementation ("com.google.android.libraries.identity.googleid:googleid:1.1.0")
}
5.次にFirebaseの方でAuthenticationからログイン方法を選択し、新しいプロバイダを追加でgoogleを選択する。
そしたら、MainActivity.kt以外にLoginScreen.ktとHomeScreen.ktを追加して下さい。
追加したらまずHomeScreen.ktとLoginScreen.ktを下記のとおりにして下さい。
@Composable
fun HomeScreen(
currentUser:FirebaseUser?,
onSignOut:() -> Unit,
){
val textStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontFamily = FontFamily.Monospace,
fontSize = 16.sp
)
Surface(
modifier = Modifier
.fillMaxSize(),
) {
Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
currentUser?.let { user ->
user.photoUrl?.let {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(it)
.crossfade(true)
.build(),
contentDescription = "profile photo",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(160.dp)
.clip(RoundedCornerShape(4.dp))
)
Spacer(modifier = Modifier.size(16.dp))
}
user.displayName?.let{
Text(
text = it,
style = textStyle,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Spacer(modifier = Modifier.size(16.dp))
}
user.email?.let{
Text(
text = "Mail ID'$it",
style = textStyle,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Spacer(modifier = Modifier.size(16.dp))
}
Text(
text = "UID:${user.uid}",
style = textStyle,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
)
Spacer(modifier = Modifier.size(16.dp))
Button(onClick = onSignOut) {
Text(
text = stringResource(id = R.string.sign_out),
style = textStyle.copy(
fontWeight = FontWeight.SemiBold
)
)
}
}
}
}
}
@Composable
fun LoginScreen(
onSignInClick:() -> Unit,
){
Surface(
modifier = modifier
.fillMaxSize()
) {
Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null,
modifier = Modifier
.size(80.dp)
)
Spacer(modifier = Modifier.height(32.dp))
Button(onClick = onSignInClick) {
Text(text = stringResource(id = R.string.sign_in))
}
}
}
}
6.ここまでは理解出来たと思います。ここからがFirebaseで実装する大部分です。
Navigation.ktを作成して下さい。Navigation.ktにFirebaseAuthを実装していきたいと思います。
@Composable
fun Navigation(
navHostController: NavHostController,
FirebaseViewModel:FirebaseViewModel,
scope:CoroutineScope,
){
val startDestination = if(FirebaseViewModel.auth.currentUser == null) Screen.Login.name else
Screen.Home.name
val context = LocalContext.current
val credentialManager = CredentialManager.create(context)
NavHost(
navController = navHostController,
startDestination = startDestination
){
composable(Screen.Login.name){
LoginScreen(
onSignInClick = {
val googleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
//WEB_CLIENT_IDはあとでMainActivityに書きます
.setServerClientId(WEB_CLIENT_ID)
.build()
val request = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
scope.launch {
try {
val result = credentialManager.getCredential(
request = request,
context = context
)
val credential = result.credential
val googleIdTokenCredential = GoogleIdTokenCredential
.createFrom(credential.data)
val googleIdToken = googleIdTokenCredential.idToken
val firebaseCredential =
GoogleAuthProvider.getCredential(googleIdToken,null)
FirebaseViewModel.auth.signInWithCredential(firebaseCredential)
.addOnCompleteListener{ task ->
if(task.isSuccessful){
navHostController.popBackStack()
navHostController.navigate(Screen.Home.name)
}
}
}catch (e:Exception){
Toast.makeText(
context,
"Error:${e.message}",
Toast.LENGTH_LONG).show()
e.printStackTrace()
}
}
}
)
}
composable(Screen.Home.name){
HomeScreen(
currentUser = FirebaseViewModel.auth.currentUser,
onSignOut = {
FirebaseViewModel.auth.signOut()
scope.launch {
credentialManager.clearCredentialState(
ClearCredentialStateRequest()
)
navHostController.popBackStack()
navHostController.navigate(Screen.Login.name)
}
}
)
}
}
}
enum class Screen{
Login,
Home
}
6.最後にFirebaseViewModelを作成して、FirebaseViewModelとMainAcitivityに追記していきたいと思います。
class FirebaseViewModel:ViewModel(){
val auth: FirebaseAuth = FirebaseAuth.getInstance()
}
// Firebaseを開いてAuthenticationのログイン方法の画面からGoogleを選んで
// その中からウェブSDK構成のウェブクライアントIDをコピーすれば良い
const val WEB_CLIENT_ID = "...."
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val navController = rememberNavController()
val scope = rememberCoroutineScope()
val FirebaseAuthViewModel = FirebaseViewModel()
Navigation(
navHostController = navController,
FirebaseViewModel = FirebaseAuthViewModel,
scope = scope,
)
}
}
}
終わり
以上になります。
これでGoogleのアカウントでログインできるようになっているはずです。(多分...)
この記事は2024年6月28日に書いていますが、もしかしたら推奨されていない形になっているかもしれません。
そこのところは考慮して下さい。よろしくお願いします。
また、問題点などが発覚したら気兼ねなくお知らせください。