지난주 Pager Layout을 배워서 활용해 보았고, 뒷부분에서는 조금 어려운 Reposity와 Hilt 맛보기를 했는데요. Repository와 Hilt를 배운 이유는 바로..! 앱에서 데이터를 활용하기 위함이겠죠?! 그리하여 이러한 데이터를 저장하고 불러올 수 있는 만능 도구인 "Firebase"와 "Chegg Prep" 앱을 연동하고 로그인 기능을 구현하기 위한 커리큘럼 시간이 진행되었습니다. 그럼 같이 한 번 따라가 보시죠!!
일단 가장 먼저 Firebase가 무엇인지 간단하게 알고 넘어가 보도록 할게요!
Firebase는 2011년 Firebase사가 개발하고 2014년 Google에 인수된 모바일 및 웹 애플리케이션 개발 플랫폼입니다. 즉, 현재는 구글에서 운영 중인 플랫폼이라고 할 수 있겠죠.
이러한 파이어베이스는 Android, iOS, 웹, Unity 등과 연결하여 사용할 수 있으며 데이터를 저장하고 앱을 지원하는 백엔드 서버, 사용자 인증, 수익 창출과 같은 앱 구축 시 필요한 다양한 기능을 제공하기 때문에 제가 만능 도구라고 표현했던 것입니다~!
사실 다른 데이터 및 서버보다도 간단한 UI와 사용방법 그리고 여러 참고 자료들로 인해 많은 사람들이 앱을 만들 때에는 파이어베이스를 우선순위로 사용하고자 마음을 먹는 것이라고 생각합니다.
웹/머신러닝 멤버분들도 기회가 된다면 Firebase 꼭 한 번 사용해 보시기 바랍니다!!
그리하여 우리는 이 Firebase로 무엇을 할 것이냐! 가장 먼저 이번 시간에 해볼 것은 앱에 구글 SignIn 기능을 구현하는 것입니다.
Firebase는 앱에서 사용자 인증 및 로그인을 쉽게 할 수 있도록 Google, Facebook, Twitter, email, phone 등의 다양한 인증 방식을 지원합니다. 우리는 그중에서도 Google을 사용해 볼 것이구요!
Android Studio에서 작업 중인 Chegg Prepp 프로젝트에서 상단 탭의 Tools 를 클릭하면 Firebase 를 찾을 수 있는데요. 클릭하면 화면 오른쪽에 Firebase를 활용할 수 있는 다양한 기능들을 보여줍니다. 그중에서도 Authentication 을 사용하여 Google Sin-in 을 구현할 수 있습니다.
사용자가 앱을 통해 구글 로그인 기능을 사용하려면 버튼이 필요하겠죠? 해당 버튼을 먼저 만들어주겠습니다!
@ExperimentalMaterialApi
@Composable
fun GoogleSignInButtonUi(
text: String = "",
loadingText: String = "",
onClick: () -> Unit
) {
var clicked by remember {
mutableStateOf(false)
}
Surface(
onClick = { clicked = !clicked },
shape = MaterialTheme.shapes.medium,
border = BorderStroke(width = 1.dp, color = Color.LightGray),
color = MaterialTheme.colors.surface
) {
Row(
Modifier
.padding(
start = 12.dp,
end = 16.dp,
top = 12.dp,
bottom = 12.dp
)
.animateContentSize(
animationSpec = tween(
durationMillis = 300,
easing = LinearOutSlowInEasing
)
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Icon(
painter = painterResource(id = R.drawable.ic_google_icon),
contentDescription = "Google SignIn Button",
tint = Color.Unspecified
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = if (clicked) loadingText else text)
if (clicked) {
Spacer(modifier = Modifier.width(16.dp))
CircularProgressIndicator(
modifier = Modifier
.height(16.dp)
.width(16.dp),
strokeWidth = 2.dp,
color = MaterialTheme.colors.primary
)
onClick()
}
}
}
}
이렇---게에ㅔㅔ 긴 코드를 작성하면, 위의 사진에서 보시는 것처럼 버튼을 구현하실 수 있답니다. 우리의 Jetpack Compose 덕분에 코드가 좀 길어질 수는 있지만 클릭 이벤트에 대한 처리도 한 번에 가능하다는 점은 아주 큰 장점이죠!!
fun getGoogleSignInClient(context: Context): GoogleSignInClient {
val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(context.getString(R.string.web_client_id))
.build()
Log.d("client", R.string.web_client_id.toString())
return GoogleSignIn.getClient(context, signInOptions)
}
Google SignIn과의 소통을 위해서는 Firebase 연동 시에 프로젝트에 추가해 줬던 google-service.json 파일이 필요합니다. 그 파일 안에 있는 "oauthclient" 의 "client_id" 를 사용해야 하기 때문이죠. 해당 client_id를 복사한 뒤에 res 폴더 -> values 폴더 안에 "strings.xml" 를 열어 그 안에 선언해 줍니다. 우리는 web_client_id라는 이름으로 선언을 해주었기 때문에 사용할 때는 R.string.web_client_id로 사용할 수 있습니다. 해당 id는 Google SignIn을 위한 요청 토큰으로 사용됩니다.
private fun firebaseAuthWithGoogle(
idToken: String,
signIn: (String, String) -> Unit
) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
auth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d("Firebase", "signInWithCredential:success")
signIn(auth!!.currentUser!!.email!!, auth!!.currentUser!!.displayName!!)
}
else {
// If sign in fails, display a message to the user.
Log.d("Firebase", "signInWithCredential:failure", task.exception)
}
}
}
Android에서 코틀린을 사용하면 "Flow"에 대한 이야기를 자주 접하게 되실 텐데요. 코루틴에서 flow는 여러 값들을 순차적으로 내보낼 수 있는 유형을 말한다고 해요. 즉, flow를 사용하면 DB로부터 실시간 업데이트를 받을 수 있는 것이죠.
이러한 Flow는 flow builder API들을 통해서 만들 수 있는데요. StateFlow가 바로 이 flow를 통해 상태 업데이트를 UI 표현을 위해 최적으로 내보내주는 Flow API입니다.
그리하여 StateFlow 는 현재 상태에서 state가 업데이트되면 해당 상태의 변화를 관찰하고 있다가 변화 흐름을 전달해 주는 녀석입니다. 이러한 StateFlow도 코드에 잘 녹여 낸다면 사용자에게 UI를 통해 데이터를 빠르게 효율적으로 보여줄 수 있겠죠?!
이렇게 본격 8주 차에 달하는 Chegg Prepp 클론 코딩 커리큘럼이 마무리되었는데요...! 미처 다루지 못한 데이터 구조화 및 처리 등은 종강 이후의 추가 커리큘럼을 통해 진행될 예정입니다. 마지막 특별 커리큘럼까지 많은 기대와 관심 부탁드립니다~! 그럼 종강 후에 만나요~ 안녕~!😊