초보 dogfootruler

3. 개초보도 할 수 있는 Firebase 인증(Google 로그인, 로그아웃, 회원탈퇴) 본문

StudyRoom;/Android;

3. 개초보도 할 수 있는 Firebase 인증(Google 로그인, 로그아웃, 회원탈퇴)

킹갓우부 2019. 11. 3. 19:10

어제는 Firebase를 안드로이드와 연결하였다.

오늘은 연결된 Firebase를 이용해, Google로그인을 만들어 보려고 한다.

연결을 하지 않았다면, 

2019/11/02 - [혼자공부방/안드로이드 공부] - 1. 개초보도 할 수 있는 Firebase 연결(간단 SHA키 등록까지)

 

1. 개초보도 할 수 있는 Firebase 연결(간단 SHA키 등록까지)

오랜만에 다시 티스토리에 왔다.... 졸작도 끝났고... 취업은 아직이라 시간이 떠버렸다... 졸작을 하면서 느꼈는데, Firebase도 연결을 못하는 친구들이 많다는 것을 알았다.. 외부 DB연결은 하면서.. Firebase를..

chobodogfootruler.tistory.com

Firebase ->Authentication -> 로그인 방법으로 들어가자

그러면 아래의 화면이 나오는데, 지금은 모든 로그인 방법이 중지 되어있다. 아래에 Google을 눌러서 중지를 풀어주자!

 

일단, 만들고자 하는 어플리케이션은 첫 화면에 로그인 할 수 있는 화면(Main)이 나오고,

로그인이 되면 로그아웃 또는 회원탈퇴 할수 있는 화면(After)을 만들어 주는것이다.

또한, 계속 로그인 해서 들어가는 것이 아닌, 로그아웃 또는 회원탈퇴를 하지 않았다면

바로 After화면으로 넘어가게 만들어보자

 


1. 인증 라이브러리를 받아오자 

build.gradle(app)으로 들어가서 implementation을 해주자!

넣어준 후에는 Snyc Now를 누르자!

  implementation 'com.google.firebase:firebase-auth:19.0.0'
  implementation 'com.google.android.gms:play-services-auth:17.0.0'

2. 보면 Glide를 만들고 난 후의 XML이다. 이미지뷰를 넣고 싶지 않으신분들은 빼면 된다!

위의 라이브러리를 추가하면 구글 버튼을 만들 수 있다.

 <com.google.android.gms.common.SignInButton
        android:id="@+id/signInButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true" />

 

아래의 XML화면은 로그인 후 갈 화면이다. 간단하게 만들었다.

 <Button
        android:id="@+id/btn_logout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="로그아웃"/>

    <Button
        android:id="@+id/btn_revoke"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="회원탈퇴"/>

 3. 로그인 Activity를 만들어보려고 한다.

이것이 은근히 귀찮은 작업이다. 가져오는 함수가 많으니 천천히 따라하자.

일단 필요한 변수들을 전역변수로 넣어주자.

 private FirebaseAuth mAuth = null;
 private GoogleSignInClient mGoogleSignInClient;
 private static final int RC_SIGN_IN = 9001;
 private SignInButton signInButton;

그리고 onCreate안에 아래의 코드를 써주자.

아래 FirebaseAuth.getInstance라는 코드는 FirebaseAuth를 사용하기 위해서 인스턴스를 꼭 받아오기 위해 써주어야한다.

signInButton = findViewById(R.id.signInButton);
mAuth = FirebaseAuth.getInstance();

구글의 Sign in 즉 로그인 하기 위해서 구성되어야할 코드이다!

이 또한 꼭 서주어야 로그인을 만들 수 있다.

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();
 mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

중간에 보면 아래의 코드가 있다. 이 코드 같은 경우는 안써도 된다.

다만 로그인 하고 다음에 어플리케이션을 켰을때 바로 다음 화면으로 넘어가게 하고 싶다면 이 코드를 안에 넣어주자!

 if (mAuth.getCurrentUser() != null) {
            Intent intent = new Intent(getApplication(), AfterActivity.class);
            startActivity(intent);
            finish();
        }

signIn()함수를 만들어 주어야 한다. onCreate밖에다가 적어주자!

private void signIn() {
    Intent signInIntent = mGoogleSignInClient.getSignInIntent();
    startActivityForResult(signInIntent, RC_SIGN_IN);
}

그리고 아래의 onActivityResult()를 구현해주자! 필요로 하는 코드가 상당하다.

마지막 하나의 코드가 더 남았다.

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                firebaseAuthWithGoogle(account);
            } catch (ApiException e) {
            }
        }
    }

대망의 하이라이트 코드 firebaseAuthWithGoogle()를 만들어주자!

이것 또한 구글 문서에서 그대로 가져왔다. 

참고로 Snackbar.make부분은 빼주고 싶으면 빼주면 된다. 

 private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Snackbar.make(findViewById(R.id.layout_main), "Authentication Successed.", Snackbar.LENGTH_SHORT).show();
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Snackbar.make(findViewById(R.id.layout_main), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
                            updateUI(null);
                        }
                    }
                });
    }

여기까지 왔다면 거의 다왔다. 마지막으로 updateUI()만들면 된다. 

여기에서는 로그인 후에 AfterActivity로 intent로 옮기겠다는 소리다!

사용하는 사람마다 다양하게 수정해서 쓰길 바란다.

 private void updateUI(FirebaseUser user) { //update ui code here
        if (user != null) {
            Intent intent = new Intent(this, AfterActivity.class);
            startActivity(intent);
            finish();
        }
    }

4. 넘어갈 화면 AfterActivity를 만들자! 넘어갈 화면에는 로그아웃과 회원탈퇴가 있는데,

위의 로그인 구현보다 훨씬 쉽다.

전역변수로 일단 아래의 코드를 넣어주고...

private FirebaseAuth mAuth ;

위에서 말했듯이 FirebaseAuth를 사용하기 위해서 꼭 getInstance를 해주자!

 mAuth = FirebaseAuth.getInstance();

로그아웃 구현 함수이다! 너무나 간단하다.

 private void signOut() {
        FirebaseAuth.getInstance().signOut();
    }

회원탈퇴 구현 함수이다. 이것 또한 너무나 간단하다.

private void revokeAccess() {
        mAuth.getCurrentUser().delete();
    }

아래에는 버튼을 눌렀을 때, 로그아웃 또는 회원탈퇴 함수를 불러 종료시키는 것이다.

구현하고 finishAffinity()를 사용했는데, finish()가 아니라 이 함수를 사용한 것은 완전히 어플리케이션을 종료시키기 위해서다!

5. 구현 화면이다 너무나 잘된다.

 

Firebase를 이용해서 Google로그인, 로그아웃, 회원탈퇴까지 만들어보았다.

처음 Firebase를 만졌을 때는 신세계였다. 지금은 너무나 익숙해졌지만, 사용하면 편하니 한번 사용해보았으면 좋겠다

 

p.s 전체 구현코드

MainActivity

package com.example.firebase_test;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;

public class MainActivity extends AppCompatActivity {
    private FirebaseAuth mAuth = null;
    private GoogleSignInClient mGoogleSignInClient;
    private static final int RC_SIGN_IN = 9001;
    private SignInButton signInButton;

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

        TextView tvContents = (TextView)findViewById(R.id.tv_contents);
        ImageView ivGlide = (ImageView)findViewById(R.id.iv_glide);
        signInButton = findViewById(R.id.signInButton);

        Glide.with(this)
                .load("http://goo.gl/gEgYUd")
                .override(300, 200)
                .fitCenter()
                .into(ivGlide);

        mAuth = FirebaseAuth.getInstance();
        if (mAuth.getCurrentUser() != null) {
            Intent intent = new Intent(getApplication(), AfterActivity.class);
            startActivity(intent);
            finish();
        }
        // Configure Google Sign In
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        signInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                signIn();
            }
        });
    }
    // [START signin]
    private void signIn() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                firebaseAuthWithGoogle(account);
            } catch (ApiException e) {
            }
        }
    }

    private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Snackbar.make(findViewById(R.id.layout_main), "Authentication Successed.", Snackbar.LENGTH_SHORT).show();
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Snackbar.make(findViewById(R.id.layout_main), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
                            updateUI(null);
                        }
                    }
                });
    }

    private void updateUI(FirebaseUser user) { //update ui code here
        if (user != null) {
            Intent intent = new Intent(this, AfterActivity.class);
            startActivity(intent);
            finish();
        }
    }
}

AfterActivity

package com.example.firebase_test;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.auth.FirebaseAuth;

public class AfterActivity extends AppCompatActivity implements View.OnClickListener {
    Button btnRevoke, btnLogout;
    private FirebaseAuth mAuth ;

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

        btnLogout = (Button)findViewById(R.id.btn_logout);
        btnRevoke = (Button)findViewById(R.id.btn_revoke);

        mAuth = FirebaseAuth.getInstance();

        btnLogout.setOnClickListener(this);
        btnRevoke.setOnClickListener(this);
    }

    private void signOut() {
        FirebaseAuth.getInstance().signOut();
    }

    private void revokeAccess() {
        mAuth.getCurrentUser().delete();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_logout:
                signOut();
                finishAffinity();
                break;
            case R.id.btn_revoke:
                revokeAccess();
                finishAffinity();
                break;
        }
    }
}

 

Comments