Skip to content

Instantly share code, notes, and snippets.

@Nunocky
Last active March 1, 2025 02:48
Show Gist options
  • Save Nunocky/eb182887a3fd0f23a4457bdbd9994fdd to your computer and use it in GitHub Desktop.
Save Nunocky/eb182887a3fd0f23a4457bdbd9994fdd to your computer and use it in GitHub Desktop.
Android + Firebase
plugins {
...
alias(libs.plugins.google.services)
alias(libs.plugins.ksp)
alias(libs.plugins.hilt.android)
alias(libs.plugins.serialization)
}
android {
defaultConfig {
...
buildConfigField(
"String",
"GOOGLE_CLIENT_ID",
project.properties["google_client_id"] as String
)
}
buildFeatures {
compose = true
buildConfig = true
}
}
dependencies {
implementation(libs.dagger.hilt.android)
ksp(libs.dagger.hilt.android.compiler)
ksp(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.serialization.json)
// firebase
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.firebase.auth.ktx)
implementation(libs.play.services.auth)
implementation(libs.androidx.credentials)
implementation(libs.androidx.credentials.play.services.auth)
implementation(libs.googleid)
}
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class EmailSignInViewModel @Inject constructor() : ViewModel() {
sealed class SignInUIState {
data object Initial : SignInUIState()
data object Processing : SignInUIState()
class Success(val user: FirebaseUser) : SignInUIState()
data object Canceled : SignInUIState()
class Failed(e: Exception) : SignInUIState()
}
private val _uiState = MutableStateFlow<SignInUIState>(SignInUIState.Initial)
val uiState = _uiState.asStateFlow()
// val isProcessingSignIn = uiState.map { it is SignInUIState.Processing }
/**
* email と password でサインイン
*/
fun signIn(email: String, password: String) {
viewModelScope.launch(Dispatchers.IO) {
_uiState.value = SignInUIState.Processing
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password)
.addOnSuccessListener { result ->
_uiState.value = SignInUIState.Success(result.user!!)
}.addOnFailureListener { e ->
_uiState.value = SignInUIState.Failed(e)
}.addOnCanceledListener { _uiState.value = SignInUIState.Canceled }
}
}
}
import android.app.Application
import androidx.credentials.CredentialManager
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import org.nunocky.myfirebaseapp.BuildConfig
import javax.inject.Inject
/**
* Google Sign In
* very thanks to https://qiita.com/kisayama/items/5dc7618b76f6d86a6d55
*/
// TODO implementするライブラリのことを記載する
@HiltViewModel
class GoogleSignInViewModel @Inject constructor(
private val context: Application
) : ViewModel() {
sealed class SignInUIState {
data object Initial : SignInUIState()
data object Processing : SignInUIState()
class Success(val user: FirebaseUser) : SignInUIState()
class Failed(e: Exception) : SignInUIState()
}
private val _signInUIState = MutableStateFlow<SignInUIState>(SignInUIState.Initial)
val signInUIState = _signInUIState.asStateFlow()
private fun getSignInRequest(): GetCredentialRequest {
val googleClientId = BuildConfig.GOOGLE_CLIENT_ID
// Googleサインインリクエストを作成
val googleIdOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
googleClientId
) // nonceがあれば設定
.build()
// GetCredentialRequestを作成
return GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
}
fun signIn() {
viewModelScope.launch {
try {
_signInUIState.value = SignInUIState.Processing
val auth: FirebaseAuth = FirebaseAuth.getInstance()
val credentialManager = CredentialManager.create(context)
val request = getSignInRequest()
val credential = try {
val result =
credentialManager.getCredential(context = context, request = request)
result.credential
} catch (e: Exception) {
throw e
}
// 取得した資格情報がGoogle IDトークンであるか確認
if (credential is CustomCredential && credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
val googleIdTokenCredential =
GoogleIdTokenCredential.createFrom(credential.data)
// IDトークンを取得
val googleIdToken = googleIdTokenCredential.idToken
// Firebaseの認証情報を作成
val firebaseCredential = GoogleAuthProvider.getCredential(googleIdToken, null)
// Firebaseでサインイン処理を実行
val authResult = auth.signInWithCredential(firebaseCredential).await()
// サインイン成功時のユーザー情報を取得
val firebaseUser = authResult.user
if (firebaseUser != null) {
_signInUIState.value = SignInUIState.Success(firebaseUser)
}
} else {
// アカウント情報が見つからない時の処理
_signInUIState.value = SignInUIState.Failed(Exception("account not found"))
}
} catch (e: Exception) {
_signInUIState.value = SignInUIState.Failed(e)
}
}
}
}
[versions]
serialization = "2.1.10"
kotlinxSerializationJson = "1.8.0"
ksp = "2.1.10-1.0.30"
hiltAndroid = "2.55"
hiltAndroidCompiler = "2.55"
hiltCompiler = "1.2.0"
hiltNavigationCompose = "1.2.0"
navigationCompose = "2.8.7"
google-services = "4.4.2"
firebaseBom = "33.9.0"
firebaseAuthKtx = "23.2.0"
playServiceAuth = "21.3.0"
credentials = "1.5.0-rc01"
googleid = "1.1.1"
[libraries]
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
dagger-hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hiltAndroidCompiler" }
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltCompiler" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx" }
firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx", version.ref = "firebaseAuthKtx" }
play-services-auth = { module = "com.google.android.gms:play-services-auth", version.ref = "playServiceAuth" }
androidx-credentials = { module = "androidx.credentials:credentials", version.ref = "credentials" }
androidx-credentials-play-services-auth = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "credentials" }
googleid = { module = "com.google.android.libraries.identity.googleid:googleid", version.ref = "googleid" }
[plugins]
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hiltAndroid" }
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "serialization" }
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.google.services) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.hilt.android) apply false
alias(libs.plugins.serialization) apply false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment