Firebase로 로그인 처리하기
2021. 12. 1. 08:53ㆍAndroid Development
<?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">
<Button
android:id="@+id/firebaseauthbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FCM auth"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_main.xml
package com.example.fcmtest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// mainActivity자체에 클릭 이벤트 설정.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button firebaseauthbtn = findViewById(R.id.firebaseauthbtn);
firebaseauthbtn.setOnClickListener(this);
// 기존에는 익명 내부 클래스로 클릭 이벤트를 처리했지만,
// 이번에는 메인택티비티에 해당 이벤트를 처리하도록 변경.
}
//View.OnClickListener 의 강제 구현 메소드.
@Override
public void onClick(View v) {
Intent i = null;
i = new Intent(this, AuthActivity.class);
startActivity(i);
// 기존 액티비티에서 AuthActivity 호출.
}
}
MainActivity.java
<?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=".AuthActivity">
<ImageView
android:id="@+id/topimg"
android:layout_width="120dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/titletxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FCM auth"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topimg" />
<Button
android:id="@+id/firebaseui"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="삽입형 인증 솔루션"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titletxt" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/firebaseui" />
</androidx.constraintlayout.widget.ConstraintLayout>
Auth_Activity.xml
package com.example.fcmtest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class AuthActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
Button firebaseauthbtn = findViewById(R.id.firebaseui);
firebaseauthbtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent i = null;
i = new Intent(this, FirebaseUIActivity.class);
startActivity(i);
}
}
AuthActivity.java
<?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=".FirebaseUIActivity">
<ImageView
android:id="@+id/topimg"
android:layout_width="120dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/titletxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FCM auth"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topimg" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="인증"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titletxt" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="google"
android:checked="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_firebaseui_activity.xml
package com.example.fcmtest;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
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.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
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 FirebaseUIActivity extends AppCompatActivity implements
View.OnClickListener {
// 파이어 베이스에 (로그인 인증) 정보를 요청하고 결과를 리턴 받음.
private static final String TAG = "GoogleActivity";// 디버그용 태그
private FirebaseAuth mAuth;// 파이어 베이스 인증 객체
private GoogleSignInClient mGoogleSignInClient;// 구글인증 객체
ActivityResultLauncher<Intent> someActivityResultLauncher = null;
// 양방향 액티비티에서 응답 처리 콜백 객체.
Button firebaseauthbtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_firebase_uiactivity);
GoogleSignInOptions gso
= new
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// 액티비티를 준비하면서 구글 인증 객체 준비.(토큰과 이메일을 요청)
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
// 구글 인증 객체 초기화.(로그인 시도 구글 계정의 정보를 담을 객체)
mAuth = FirebaseAuth.getInstance();// 파이어 베이스 인증 객체 초기화.
// 싱글톤, 파이어베이스에서 인증정보 가져오기.
// 패키지 정보, 이메일 정보 확인.
firebaseauthbtn = findViewById(R.id.button2);
firebaseauthbtn.setOnClickListener(this);
someActivityResultLauncher
= registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
Task<GoogleSignInAccount> task
=
GoogleSignIn.getSignedInAccountFromIntent(data);
// 인텐트로 부터 구글 로그인 정보를 가져옴.
try {
// Google Sign In was successful, authenticatewith Firebase
GoogleSignInAccount account
= task.getResult(ApiException.class);
Log.d(TAG, "firebaseAuthWithGoogle:" +
account.getId());
//ok
firebaseAuthWithGoogle(account.getIdToken(),
data);
} catch (ApiException e) {
// Google Sign In failed, update UIappropriately
Log.w(TAG, "Google sign in failed", e);
}
} else {
Log.d(TAG, "no_k");
}
}
});
}
private void firebaseAuthWithGoogle(String idToken, Intent data) {
AuthCredential credential
= GoogleAuthProvider.getCredential(idToken, null);
// 인증 토큰을 이용하여 자격 증명을 인증
// 파이어베이스에 구글 인증을 전달하여 인증 처리하고,
mAuth.signInWithCredential(credential).addOnCompleteListener(this
, new OnCompleteListener<AuthResult>() {
// 구글 로그인 정보를 이용하여 파이어베이스 인증이 완료 됐다면,
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");//ok
FirebaseUser user = mAuth.getCurrentUser();
// 파이어베이스 인증 유저명 확인.
Log.d(TAG, "user : " + user);
// 접속 유저 갱신.
// 처리후 결과 표시. 내부 클래스.
go(data);
} else {
Log.w(TAG, "signInWithCredential:failure"
, task.getException());
updateUI(null);
}
}
});
}
private void go(Intent data) {
Log.d(TAG, "go");
Intent i = new Intent(this, SignedInActivity.class);// intent 생성불가.
i.putExtras(data);
startActivity(i);
}
private void updateUI(FirebaseUser user) {
Log.d(TAG, "user : " + user);
}
@Override
public void onClick(View v) {
Log.d(TAG, "signin");
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
//startActivityForResult(signInIntent, RC_SIGN_IN);// deprecated이지만 현재 동작함.
// 구글 인증으로 정보를 보내고, 인증을 기다림.
someActivityResultLauncher.launch(signInIntent);
}
}
FirebasUIActivity.java
<?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=".SignedInActivity">
<ImageView
android:id="@+id/topimg"
android:layout_width="120dp"
android:layout_height="120dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/toptxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="signed in"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topimg" />
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toptxt"
app:layout_constraintVertical_bias="0.027">
<Button
android:id="@+id/sign_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="sign out" />
<Button
android:id="@+id/delete_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="del account" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/profilelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/ll"
tools:layout_editor_absoluteX="1dp">
<ImageView
android:id="@+id/user_profile_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/user_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/user_profile_picture"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/user_display_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/user_enabled_providers"
app:layout_constraintStart_toEndOf="@+id/user_profile_picture"
app:layout_constraintTop_toBottomOf="@+id/user_email" />
<TextView
android:id="@+id/user_enabled_providers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/user_profile_picture" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/idp_token_layout"
android:layout_width="409dp"
android:layout_height="420dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/profilelayout">
<TextView
android:id="@+id/idtokentxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="token"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/idp_token"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="n/a"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/idtokentxt" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_signed_in.xml
package com.example.fcmtest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.IdpResponse;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GetTokenResult;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.UserInfo;
public class SignedInActivity extends AppCompatActivity implements
View.OnClickListener {
// Identi provider response : 식별 공급자 응답.
private IdpResponse mIdpResponse;// 파이어베이스 인증처리 결과 식별값 저장.
private static final String TAG = "SignedInActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirebaseUser currentUser =
FirebaseAuth.getInstance().getCurrentUser();
// 현재 사용자를 얻어내고,
if (currentUser == null) {
finish();// 사용자가 없다면 결과 액티비티 종료.
//return;
}
mIdpResponse = IdpResponse.fromResultIntent(getIntent());
// 앞의 인증에서 보내준 데이터를 읽어와서.
Log.d(TAG, "onCreate_token :" + mIdpResponse);// null
setContentView(R.layout.activity_signed_in);
populateProfile();
populateIdpToken();
Button signoutbtn = findViewById(R.id.sign_out);
signoutbtn.setOnClickListener(this);
Button deleteuser = findViewById(R.id.delete_account);
deleteuser.setOnClickListener(this);
}
private void populateIdpToken() {
Log.d(TAG, "token :" + mIdpResponse);// null
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
.addOnCompleteListener(new
OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
if (idToken == null) {// 토큰이 널이라면 숨김.
findViewById(R.id.idp_token_layout).setVisibility(View.GONE);
} else {
((TextView)
findViewById(R.id.idp_token)).setText(idToken);
// 파이어베이스 인증을 통해서 찾아온 토큰값을 텍스트뷰에 표시.
Log.d(TAG, "token :" + idToken);
}
} else {
// Handle error -> task.getException();
}
}
});
}
private void populateProfile() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// 파이어베이스를 통해서 접속한 사용자 정보를 가져와서
TextView emailtxt = findViewById(R.id.user_email);
emailtxt.setText(
TextUtils.isEmpty(user.getEmail()) ? "No email" :
user.getEmail());
// 사용자의 이메일 정보 표시
TextView usernametxt = findViewById(R.id.user_display_name);
usernametxt.setText(
TextUtils.isEmpty(user.getDisplayName()) ? "No display name"
: user.getDisplayName());
// 사용자의 이름 표시
StringBuilder providerList = new StringBuilder(100);
providerList.append("Providers used: ");// 인증 주체 표시
if (user.getProviderData() == null ||
user.getProviderData().isEmpty()) {
providerList.append("none");
} else {
for (UserInfo profile : user.getProviderData()) {
String providerId = profile.getProviderId();
if (GoogleAuthProvider.PROVIDER_ID.equals(providerId)) {
providerList.append("Google");
} else {
providerList.append(providerId);
}
}
}
TextView userenabled = findViewById(R.id.user_enabled_providers);
userenabled.setText(providerList);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_out:
signOut();
break;
case R.id.delete_account:
deleteAccountClicked();
break;
default:
break;
}
}
private void deleteAccountClicked() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setMessage("Are you sure you want to delete this account?")
.setPositiveButton("Yes, nuke it!"
, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int
i) {
deleteAccount();
}
})
.setNegativeButton("No", null)
.create();
dialog.show();
Log.d(TAG, "deleteAccountClicked()");
}
private void deleteAccount() {
// 파이어베이스에 딜리트 메소드 호출,
// 삭제 처리가 완료되면 현재 액티비티는 종료.
AuthUI.getInstance()
.delete(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
finish();
} else {
}
}
});
}
private void signOut() {
// 파이어베이스에 사인아웃 처리 요청함.
AuthUI.getInstance()
.signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
finish();
} else {
}
}
});
Log
.
d
(TAG, "signOut()");
}
}
SignedInActivity.java
'Android Development' 카테고리의 다른 글
Friebase 사용해서 push message 보내기 (0) | 2021.12.02 |
---|---|
Firebase_RealtimeDatabase 사용 해보기. (0) | 2021.12.01 |
Google Firebase 환경설정. (0) | 2021.11.29 |
Android semiProject (0) | 2021.11.24 |
Android Studio 13일차 (0) | 2021.11.17 |