코딩하는 해달이

[Android Studio] Firebase 구글 로그인 구현하기 2 본문

개인 공부/Android Studio

[Android Studio] Firebase 구글 로그인 구현하기 2

코딩하는 해달 2022. 10. 1. 15:49

Version & 참고 링크

더보기

Version

 -운영체제 : Window 10

 -PYTHON : python 3.10.6 64-bit

 -Visual Studio Code : Visual Studio Code 1.70.1(user setup)

 -Android Studio : android-studio-2021.2.1.15-windows

 -MySQL : 8.0.29

 

이 글은 아래의 링크를 바탕으로 작성한 글입니다.

(제가 이해한 대로 글을 쓴 것이므로 틀린 내용이 있을 수도 있습니다.)

 

https://chobodogfootruler.tistory.com/30

 

https://firebase.google.com/docs/auth/android/google-signin?hl=ko&authuser=0

 

https://velog.io/@yongin01/%EC%8A%A4%ED%84%B0%EB%94%94%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EA%B5%AC%EA%B8%80%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

https://javapp.tistory.com/143

 

https://velog.io/@ows3090/Android-OAuth%EB%9E%80-Firebase-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84-%EC%8B%9C-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%A0%81%EC%9A%A9%EB%90%98%EB%8A%94%EC%A7%80-%ED%99%95%EC%9D%B8%ED%95%B4%EB%B3%B4

 

이제 구글 로그인 구현을 시작해봅시다.

 

firebase를 앱에 등록하지 못하신 분은 이전 글을 보고 오시면 도움이 되실겁니다.

[Android Studio] Firebase 구글 로그인 구현하기

 

일단 화면의 흐름을 확인해보면 

이런식으로 만들어 볼 생각입니다. 그러니까 화면마다 파일이름을 매치시켜보면

로그인 화면 = login_activity.xml, LoginActivity.java, GoogleLogin.java

메인 화면 = activity_main.xml, MainActivity.java

이렇게 되어있고 로그인 되어있는지 판단은 메인 액티비티에서 할 생각입니다.

 

그럼 메인 액티비티의  xml부터 구현해봅시다.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="34sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/logoutButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="34sp"
        app:layout_constraintBottom_toTopOf="@+id/logoutButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>

이렇게 넣으면 아래의 사진처럼 나오는데

로그인이 제대로 되었는지 확인해야 하잖아요?

그래서 위의 TextView는 구글 계정을 출력할거고 아래의 TextView는 이름을 출력할겁니다.

그 아래의 버튼은 로그아웃버튼이구요.

이제 메인 화면의 기능을 구현해봅시다. MainActivity가 onCreate 될 때, 현재 유저를 불러오고 로그인 되어있지 않으면 바로 LoginActivity로 보냅니다. 그렇지 않으면 계정과 이름을 표시합니다. 로그아웃 버튼은 앱의 사용자를 로그아웃 시키고 LoginActivity로 화면을 옮깁니다.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private TextView TextView;
    private TextView TextView2;
    private Button btnLogout;

    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView = findViewById(R.id.textView);
        TextView2 = findViewById(R.id.textView2);
        btnLogout = findViewById(R.id.logoutButton);

        if(FirebaseAuth.getInstance().getCurrentUser() == null) { // 앱을 실행했을 때 로그인이 되어있지 않을 경우
            Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
            startActivity(intent);
            finish();
        } else { // 로그인이 되어있을 경우
            FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
            TextView.setText("이메일 : " + user.getEmail());
            TextView2.setText("닉네임 : " + user.getDisplayName());
        }

        btnLogout.setOnClickListener(new View.OnClickListener() { // 로그아웃 버튼
            @Override
            public void onClick(View view) {
                mAuth.getInstance().signOut();
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
                finish();
            }
        });

    }

이젠 로그인 버튼을 만들어 봅시다.

login_activity.xml 파일입니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- 구글 로그인 버튼 -->
    <com.google.android.gms.common.SignInButton
        android:id="@+id/GsignInButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

이렇게 구글 로그인 버튼을 만들어줍니다. (위치는 적당히 지정해줍시다.)

그 후에 로그인 버튼을 눌렀을 때 새 인텐트를 열어서 Google로그인을 하는 곳으로 보내주는 코드입니다.

LoginActivity.java

public class LoginActivity extends AppCompatActivity {
    private TextView mobileTextView;

    private SignInButton Gbutton;
    private Button Kbutton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_activity);

        if(FirebaseAuth.getInstance().getCurrentUser() != null) {
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(intent);
        }
        else {
            Gbutton = findViewById(R.id.GsignInButton); // 구글 로그인 버튼

            // 구글 로그인 버튼 클릭 리스너
            Gbutton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(getApplicationContext(), GoogleLogin.class);
                    startActivity(intent);
                    finish();
                }
            });

        }
    }
}

이제 로그인을 시켜야겠죠?

구글 로그인 후 firebase에 등록까지하는 코드입니다. 로그인이 성공적으로 끝나면 메인 액티비티로  돌아갑니다.

GoogleLogin.java

public class GoogleLogin extends AppCompatActivity {
    private static final String TAG = "GoogleActivity";
    private static final int RC_SIGN_IN = 9001; // RC_SIGN_IN : 구글 로그인 결과(result) 상수
    private FirebaseAuth mAuth; // FirebaseAuth : firebase 인증 객체
    private GoogleSignInClient mGoogleSignInClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 파이어베이스 인증(firebaseauth) 호출
        mAuth = FirebaseAuth.getInstance();

        // 구글 로그인 구성
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                // GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN): 추가 로그인 옵션을 지정
                // DEFAULT_SIGN_IN : 구글 로그인의 기본 구성
                .requestIdToken(getString(R.string.default_web_client_id))
                // requestIdToken(문자열 serverClientId) : 인증된 사용자의 문자열 ID토큰이 요청되게 지정
                .requestEmail()
                // requestEmail() : 애플리케이션에서 사용자 이메일 정보를 요청
                .build();
        // build() : GoogleSignInOptions 개체를 빌드

        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        // GoogleSignIn.getClient(Activity 활동, GoogleSignInOption 옵션,) : 옵션에 해당하는 새 인스턴스 생성


        googlelogin();

    }

    private void googlelogin() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        // .getSignInIntent(); : 로그인 시작 하는 Intent 생성
        // Log.d("111",signInIntent.toString());
        // Intent :  앱 구성요소간 작업 수행을 위한 정보를 전달하는 객체

        startActivityForResult(signInIntent, RC_SIGN_IN);
        // startActivityForResult : 새 액티비티를 열고 결과코드 전달
    }

    // 구글 로그인
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 로그인을 시도한 경우
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            // GoogleSignInAccount : 로그인 한 사용자의 기본 계정정보를 보유하는 클래스
            // .getSignedInAccountFromIntent(data) : GoogleSignInAccount를 통해 시작된 관련활동에 대한 결과데이터 반환
            try { // 구글 로그인 후 firebase 인증 파트
                GoogleSignInAccount account = task.getResult(ApiException.class);
                // 계정정보에 문제가 있는지 확인 (문제가 있다면 예외 반환)
                // .getResult() : task의 결과 반환
                Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
                // .getId() : Google계정의 고유한 ID를 반환
                firebaseAuthWithGoogle(account.getIdToken());
                // firebaseAuthWithGoogle : firebase에 사용자 인증정보를 넘겨줌(아래에 정의되어 있음)
                // .getIdToken() : 서버에 보낼 수 있는 ID토큰 반환
            } catch (ApiException e) {
                // 로그인 실패
                Log.w(TAG, "Google sign in failed", e);
            }
        }
    }

    // 구글 로그인 firebase 인증
    private void firebaseAuthWithGoogle(String idToken) {
        AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
        // AuthCredential : 인증 자격 증명 클래스
        // .getCredential(string id토큰, string 엑세스 토큰) : 구글에서 제공하는 id토큰과 엑세스토큰을 사용해 인증
        mAuth.signInWithCredential(credential)
                // .signInWithCredential(credential) : 지정된 자격 증명을 사용해서 비동기식으로 로그인
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    // .addOnCompleteListener() : 동일한 리스너에서 성공과 실패를 처리할 때 사용
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // task.isSuccessful() : task가 성공적으로 완료되었으면 true, 그렇지 않으면 false
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInWithCredential:success");
                            Toast.makeText(getApplicationContext(), "성공했습니다.(구글 로그인)", Toast.LENGTH_LONG).show();
                            FirebaseUser user = mAuth.getCurrentUser();
                            // .getCurrentUser() : 현재 로그인 한 사용자 가져오기 로그인 한 사용자가 없으면 null 반환
                            Intent intent = new Intent(GoogleLogin.this, MainActivity.class);
                            startActivity(intent);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(getApplicationContext(), "실패했습니다.(구글 로그인)", Toast.LENGTH_LONG).show();
                        }
                        finish();
                    }
                });
    }

}

이렇게 안드로이드 - Firebase - 구글 간편 로그인을 구현해보았습니다.

아무래도 Firebase에서 지원을 해주는 로그인이다보니 조금 편하게 진행한 것같습니다. 다음엔 카카오 로그인도 도전해 볼건데 잘 할 수 있을지 모르겠네요 ㅠㅠ

반응형
Comments