본문 바로가기
⛏️ | 개발 기록/⏰ | Schedule Planner

[Android, Kotlin] Compose로 Firebase Google Login 구현하기 (8)

by immgga 2023. 11. 9.

오랜만에 Planner V2 개발일지이다.

요즘 다른 활동(코테, 타 프로젝트)을 하느라 Planner V2를 잠시 놓았었는데

이제 다시 시작해볼까 한다.

 

이번에는 본격적인 기능 개발로 Firebase Google Login을 구현해 보도록 하겠다.

평범한(?) Planner에 구글 로그인을 넣은 이유는 로그인된 유저 정보를 이용해 일정들을 따로 Firebase Database에 저장하기 위해서이다.

 

그러면 바로 필자가 구글 로그인을 구현한 과정을 알아보자.

1. 라이브러리 추가하기

Firebase Auth 라이브러리를 추가해 주자.

implementation("com.google.firebase:firebase-auth:22.2.0")
implementation("com.google.android.gms:play-services-auth:20.7.0")

2개의 라이브러리를 추가해 주자.

 

2. Firebase Authentication 연결하기

로그인 기능을 구현하기 전에 연결한 Firebase 프로젝트에서 구글 로그인을 허용해 주는 작업을 해주어야 한다.

이 작업은 검색하면 많이 나오기 때문에 간단하게 보여주도록 하겠다.

Firebase 프로젝트에서 Authentication 탭으로 들어간 다음 Sign-in method로 들어가면, 로그인 제공업체를 설정할 수 있는 화면이 나오는데 Google을 사용 설정해 주면 된다.

Google을 사용 설정을 하고 나서, 만약 Firebase 프로젝트를 미리 Android 프로젝트와 연결했다면 기존의 google-service.json 파일을 다시 다운로드해서 overwrite 해주자.

 

3. 로그인 기능 구현

현재 Google 서비스 연결까지 완료한 상태이다.

Firebase 로그인 기능을 ViewModel에 따로 구현해 주었다.

private val _isFailState = mutableStateOf(false)
val isFailState: State<Boolean> = _isFailState

fun login(
    activityResult: ActivityResult,
    onSuccess: () -> Unit
) {
    try {
        val account = GoogleSignIn.getSignedInAccountFromIntent(activityResult.data)
            .getResult(ApiException::class.java)
        val credential = GoogleAuthProvider.getCredential(account.idToken, null)
        FirebaseAuth.getInstance().signInWithCredential(credential)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) onSuccess()
            }
    } catch (e: Exception) {
        _isFailState.value = true
    }
}

위의 코드는 구글 로그인을 해주는 코드이다.

 

이제 위에 생성한 코드를 적용해 보자.

외부의 화면으로 이동할 수 있는 launcher를 생성해 주자

val context = LocalContext.current
val launcher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.StartActivityForResult()
) {
    loginViewModel.login(activityResult = it) {
        Toast.makeText(context, "로그인이 완료되었습니다.", Toast.LENGTH_SHORT).show()
        navigateToPlan()
    }
}

XML로 구현할 때에는 OnActivityResult를 override 받아야 했지만, Compose에서는 rememberLauncherForActivityResult()가 있기 때문에 편리하게 구현할 수 있다. contract에 StartActivityForResult를 넘기고, onResult(중괄호 안)에 아까 생성한 ViewModel 코드를 넣어준다.

또한 기존에 Google Signin 버튼에 넣었던 navigation 함수도 onResult로 옮겨 주었다.

 

 

마지막으로 기존의 Google Login Button의 클릭 이벤트에 launcher를 실행시키는 코드를 추가해서 버튼을 클릭하면 구글 로그인 창이 뜨도록 만들어 보겠다.

val token = stringResource(id = R.string.default_web_client_id)
GoogleSignInButton {
    val googleSignInOptions = GoogleSignInOptions
        .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(token)
        .requestEmail()
        .build()

    val googleSignInClient = GoogleSignIn.getClient(context, googleSignInOptions)
    launcher.launch(googleSignInClient.signInIntent)
}

token 변수를 만들어서 default_web_client_id를 저장해 준다.

default_web_client_id가 없어서 오류가 발생한다면, 프로젝트에 넣은 google-service.json 파일을 연 다음

client -> oauth_client -> client_id 순서대로 찾아서 client_id를 찾은 다음

string.xml에 직접 생성해 주는 방법이 있다.

token을 설정했으면 google sign in options와 google sign in client를 정의한 후 launch를 해주면 된다.

모두 구현하였으니 이제 결과를 확인해 보자.

 

3. 구현 결과

이메일은 모자이크했습니다.

버튼을 누르면 위와 같은 구글 계정 선택 창이 뜨게 된다.

 

정리

  • 처음으로 Compose로 Firebase 서비스를 구현해 보았다. 기존에 방식과 크게 달리진 것은 없었기에 많이 애먹지는 않았던 것 같다.
  • 이제 구글 로그인을 시작으로 본격적으로 Firebase Database도 사용해 볼 텐데, 데이터베이스를 사용하는 로직을 만들 때에는 테스트 코드도 작성해 볼 생각이다.
  • 다음에는 구글 로그인 정보가 저장되어 있으면 Main 화면으로 넘어가고, 그렇지 않으면 로그인 화면이 뜨게 하는 로그인 유지 기능을 만들어 볼까 한다. 이것도 만들고 포스팅을 올려보도록 하겠다.

참고한 글

https://stackoverflow.com/questions/72563673/google-authentication-with-firebase-and-jetpack-compose

728x90

댓글