FireBase Authentication는 회원과 로그인을 위한 인증과 관련된 서비스로
3개의 회원가입 방식이 있음.
그중 email/password을 이용한 회원가입/로그인 기능을 구현할 것임.
세부 구현 내용
Firebase RealtimeDatabase에 회원 정보를 저장하기 위해 회원 정보를 담을 객체
UserAccount.java
public class UserAccount {
public UserAccount() {}
private String id;
private String name;
private String number;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
회원가입 UI
<?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"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
tools:context=".SignUpActivity">
<TextView
android:id="@+id/signUpTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:textSize="32dp"
android:text="회원가입"
android:textStyle="bold"
android:textColor="#000000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"></TextView>
<LinearLayout
android:id="@+id/signUp_linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/signUpTextView">
<TextView
android:id="@+id/signUp_idTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="이메일 *"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/signUp_idEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="예) apple@gmail.com"></EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/signUp_linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/signUp_linearLayout1">
<TextView
android:id="@+id/signUp_pwTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="비밀번호 *"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/signUp_pwEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="비밀번호를 입력해주세요."
android:inputType="textPassword"></EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/signUp_linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/signUp_linearLayout2">
<TextView
android:id="@+id/signUp_pwChkTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="비밀번호 확인 *"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/signUp_pwChkEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="비밀번호를 한 번 더 입력해주세요."
android:inputType="textPassword"></EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/signUp_linearLayout4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/signUp_linearLayout3">
<TextView
android:id="@+id/signUp_nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="이름 *"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/signUp_nameEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="예) 홍길동"></EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/signUp_linearLayout5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/signUp_linearLayout4">
<TextView
android:id="@+id/signUp_numberTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="전화번호 *"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/signUp_numberEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="예) 01012345678"></EditText>
</LinearLayout>
<android.widget.Button
android:id="@+id/signUpBtn"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="15dp"
android:text="회원가입"
android:textColor="#000000"
android:background="@drawable/button_rounded_corners"
app:layout_constraintTop_toBottomOf="@+id/signUp_linearLayout5"></android.widget.Button>
</androidx.constraintlayout.widget.ConstraintLayout>
회원가입 액티비티
SignUpActivity.java
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.HashMap;
import java.util.Map;
public class SignUpActivity extends AppCompatActivity {
Button signUpBtn;
EditText edtId, edtPw, edtPwChk, edtName, edtNumber;
private FirebaseAuth fAuth;
private DatabaseReference dRef; // 실시간 데이터베이스
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
fAuth = FirebaseAuth.getInstance(); // FirebaseAuth 초기화
dRef = FirebaseDatabase.getInstance().getReference();
signUpBtn = (Button) findViewById(R.id.signUpBtn);
edtId = (EditText) findViewById(R.id.signUp_idEditText);
edtPw = (EditText) findViewById(R.id.signUp_pwEditText);
edtPwChk = (EditText) findViewById(R.id.signUp_pwChkEditText);
edtName = (EditText) findViewById(R.id.signUp_nameEditText);
edtNumber = (EditText) findViewById(R.id.signUp_numberEditText);
signUpBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String id = edtId.getText().toString().trim();
final String pw = edtPw.getText().toString().trim();
final String pwChk = edtPwChk.getText().toString().trim();
final String name = edtName.getText().toString().trim();
final String number = edtNumber.getText().toString().trim();
if (id.isEmpty() || pw.isEmpty() || pwChk.isEmpty() || name.isEmpty() || number.isEmpty()) {
Toast.makeText(SignUpActivity.this, "모든 필드를 입력하세요.", Toast.LENGTH_SHORT).show();
return;
}
if (!pw.equals(pwChk)) {
Toast.makeText(SignUpActivity.this, "비밀번호가 일치하지 않습니다.", Toast.LENGTH_SHORT).show();
return;
}
// Firebase Authentication을 사용하여 사용자 등록
fAuth.createUserWithEmailAndPassword(id, pw)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// 사용자 등록 성공
FirebaseUser user = fAuth.getCurrentUser();
String userId = user.getUid();
// UserAccount 객체 생성 및 속성 설정
UserAccount userAccount = new UserAccount();
userAccount.setId(id);
userAccount.setName(name);
userAccount.setNumber(number);
dRef.child("UserAccount").child(userId).setValue(userAccount);
Intent intent = new Intent(SignUpActivity.this, MainActivity.class);
startActivity(intent);
} else {
// 사용자 등록 실패
Toast.makeText(SignUpActivity.this, "회원가입 실패: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
}
사용자 정보를 입력하고 회원가입 버튼을 누르면 위와 같이 Firebase의 Authentication과 Realtime Database에 사용자의 정보가 저장된 것을 볼 수 있음.
로그인 UI
<?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"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/loginTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:textSize="32dp"
android:text="로그인"
android:textStyle="bold"
android:textColor="#000000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"></TextView>
<LinearLayout
android:id="@+id/login_linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/loginTextView">
<TextView
android:id="@+id/login_idTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="아이디"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/login_idEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="ex) apple@gmail.com"></EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/login_linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/login_linearLayout1">
<TextView
android:id="@+id/login_pwTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:text="비밀번호"
android:textColor="#000000"></TextView>
<EditText
android:id="@+id/login_pwEditText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="12dp"
android:background="@drawable/edittext_rounded_border"
android:hint="비밀번호를 입력하세요."
android:inputType="textPassword"></EditText>
</LinearLayout>
<android.widget.Button
android:id="@+id/loginBtn"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="15dp"
android:text="로그인"
android:textColor="#000000"
android:background="@drawable/button_rounded_corners"
app:layout_constraintTop_toBottomOf="@+id/login_linearLayout2"></android.widget.Button>
<LinearLayout
android:id="@+id/login_linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="horizontal"
android:gravity="center"
app:layout_constraintTop_toBottomOf="@+id/loginBtn">
<TextView
android:id="@+id/findIdTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:text="아이디 찾기"
android:textColor="#aeaeae"></TextView>
<TextView
android:id="@+id/findPwTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:text="비밀번호 찾기"
android:textColor="#aeaeae"></TextView>
<TextView
android:id="@+id/signUpTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="회원가입"
android:textColor="#aeaeae"></TextView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
로그인 액티비티
MainActivity.java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class MainActivity extends AppCompatActivity {
private FirebaseAuth fAuth; // 파이어베이스 인증
private DatabaseReference dRef; // 실시간 데이터베이스
Button loginBtn;
TextView findIdTextView, findPwTextView, signUpTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText edtId, edtPw;
fAuth = FirebaseAuth.getInstance();
dRef = FirebaseDatabase.getInstance().getReference();
edtId = findViewById(R.id.login_idEditText);
edtPw = findViewById(R.id.login_pwEditText);
loginBtn = (Button) findViewById(R.id.loginBtn);
findIdTextView = (TextView) findViewById(R.id.findIdTextView);
findPwTextView = (TextView) findViewById(R.id.findPwTextView);
signUpTextView = (TextView) findViewById(R.id.signUpTextView);
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String id = edtId.getText().toString();
final String pw = edtPw.getText().toString();
if (id.isEmpty() || pw.isEmpty()) {
Toast.makeText(MainActivity.this, "아이디와 비밀번호를 입력하세요.", Toast.LENGTH_SHORT).show();
return;
}
fAuth.signInWithEmailAndPassword(id, pw).addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d("MainActivity", "로그인 시도 완료");
if (task.isSuccessful()) {
Log.d("MainActivity", "로그인 성공");
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
} else {
Log.d("MainActivity", "로그인 실패", task.getException());
Toast.makeText(MainActivity.this, "로그인 실패: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
});
findIdTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// findIdTextView를 클릭했을 때의 동작
Intent intent = new Intent(MainActivity.this, FindIdActivity.class);
startActivity(intent);
}
});
findPwTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// findPwTextView를 클릭했을 때의 동작
Intent intent = new Intent(MainActivity.this, FindPasswordActivity.class);
startActivity(intent);
}
});
signUpTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// signUpTextView를 클릭했을 때의 동작
Intent intent = new Intent(MainActivity.this, SignUpActivity.class);
startActivity(intent);
}
});
}
}
fAuth.signInWithEmailAndPassword(id, pw).addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d("MainActivity", "로그인 시도 완료");
if (task.isSuccessful()) {
Log.d("MainActivity", "로그인 성공");
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
} else {
Log.d("MainActivity", "로그인 실패", task.getException());
Toast.makeText(MainActivity.this, "로그인 실패: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
위 코드는 Firebase Authentication을 사용하여 사용자가 제공한 이메일 주소와 비밀번호로 로그인을 시도함.
fAuth.signInWithEmailAndPassword(id, pw)
여기서 fAuth는 FirebaseAuth 객체를 나타내고, signInWithEmailAndPassword() 메서드는 이메일 주소와 비밀번호를 인자로 받아 사용자를 로그인함.
사용자가 로그인 버튼을 클릭하면 사용자가 입력한 아이디와 비밀번호를 사용하여 Firebase 인증을 시도함. 로그인이 성공하면 SecondActivity로 이동하고, 실패하면 사용자에게 실패 이유를 알림
사용자가 각각의 텍스트뷰를 클릭하면 해당 화면(아이디 찾기, 비밀번호 찾기, 회원가입 화면)으로 이동