이번에는 경남드리의 부가기능과 그것을 구현하면서 배운 점에 대해 적어보려고 한다.
주요한 경남드리의 부가기능에는 회원가입, 좋아요 및 리뷰가 있다.
1)회원가입
회원가입은 FireBase의 공식문서를 참고하여 만들었다.
https://firebase.google.com/docs/auth/android/start?hl=ko&authuser=2
이 문서에 보면 신규 사용자 가입이라는 항목이 있다. 이 항목 코드를 가져와서 사용해주는데 만약 이름이나 사진을 넣어주고 싶다면 가입하는 코드 내에서 회원가입이 정상적으로 이루진 후에 유저의 정보에 이름과 사진을 추가해주는 코드가 들어가도록 구현해주면 된다.
mAuth.createUserWithEmailAndPassword(email, password)
.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
Log.d(TAG, "createUserWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
}
});
이 email과 password에 우리의 값을 넣어서 isSuccessful 시에 회원가입 시 성공인 화면이 나올 수 있도록 만들어 보겠다.
일단 회원가입에 유저정보를 받을 수 있게 틀을 xml로 작성해주자
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#AED2FF">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/back"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@drawable/backspaceimage"
android:textColor="@color/purple_700"
android:textSize="20dp" />
<TextView
android:id="@+id/signup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_weight="2"
android:gravity="center"
android:text="회원 가입"
android:textColor="@color/purple_700"
android:textSize="25dp" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="10dp"
android:layout_marginRight="30dp"
android:orientation="vertical">
<TextView
android:id="@+id/signIDtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="닉네임"
android:textColor="@color/purple_700"
android:textSize="20dp"
android:textStyle="bold" />
<EditText
android:id="@+id/signID"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="20dp"
android:background="@color/white"
android:ems="10"
android:hint=" 닉네임"
android:inputType="textPersonName"
android:text=""
android:textColor="@color/black"
android:textColorHint="#60000000" />
<TextView
android:id="@+id/signmailtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="이메일"
android:textColor="@color/purple_700"
android:textSize="20dp"
android:textStyle="bold" />
<EditText
android:id="@+id/signmail"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="20dp"
android:background="@color/white"
android:ems="10"
android:hint="이메일"
android:inputType="textPersonName"
android:text=""
android:textColor="@color/black"
android:textColorHint="#60000000" />
<TextView
android:id="@+id/signPWtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="비밀번호"
android:textColor="@color/purple_700"
android:textSize="20dp"
android:textStyle="bold" />
<EditText
android:id="@+id/signPW"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="20dp"
android:background="@color/white"
android:ems="10"
android:hint=" 비밀번호"
android:inputType="textPassword"
android:text=""
android:textColor="@color/black"
android:textColorHint="#60000000" />
<TextView
android:id="@+id/signPW2text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="비밀번호 확인"
android:textColor="@color/purple_700"
android:textSize="20dp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/signPW2"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="20dp"
android:background="@color/white"
android:ems="10"
android:hint=" 비밀번호 다시 입력"
android:inputType="textPassword"
android:text=""
android:textColor="@color/black"
android:textColorHint="#60000000" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/pwcheckbutton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="@drawable/cate_button_selector"
android:text="확인"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/signupbutton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:background="@drawable/cate_button_selector"
android:text="가입"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>
유저 닉네임과 아이디 비밀번호를 EditText로 유저가 직접 입력할 수 있도록 하였다. 그리고 비밀번호 확인버튼과 뒤로가기 버튼, 회원가입 버튼을 만들어서 누를 수 있게 구현하였다.
밑은 실제로 구현된 화면이다.
이 EditText에 있는 값을 가져온 다음 위에 있던 함수와 똑같이 작성해준다음 매개변수만 우리의 값으로 대체해 준다.
String mypw=pw.getText().toString();
String mypw2=pw2.getText().toString();
String myemail=email.getText().toString();
String myname=name.getText().toString();
if(mypw.equals(mypw2)){
mFirebaseAuth.createUserWithEmailAndPassword(myemail, mypw)
.addOnCompleteListener(signUp.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
Toast.makeText(signUp.this, "회원가입성공",Toast.LENGTH_LONG).show();
FirebaseUser user = mFirebaseAuth.getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(myname).build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
}else{
Log.d(TAG, "실패.");
}
}
});
onBackPressed();
} else {
// If sign in fails, display a message to the user.
Toast.makeText(signUp.this, "회원가입 실패",Toast.LENGTH_LONG).show();
}
}
});
}else{
Toast.makeText(signUp.this, "비밀번호가 중복체크 실패",Toast.LENGTH_LONG).show();
}
2)로그인
로그인 또한 Firebase 위의 링크의 공식문서에 잘 작성돼있다. 코드를 보자면
mAuth.signInWithEmailAndPassword(email, password)
.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
Log.d(TAG, "signInWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.getException());
Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
}
});
이 email과 password에 우리의 값을 넣어서 isSuccessful 시에 로그인 성공인 화면이 나올 수 있도록 만들어 보겠다.
일단 기반이 되는 xml 파일을 보자면 회원가입과 동일하게 입력받는 부분이 EditText로 구현되어 있다. 또한 로그인 할 수 있는 버튼과 회원가입화면으로 넘어갈 수 있는 회원가입 글자도 클릭가능하게 만들어 주었다.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#AED2FF"
tools:context=".Login">
<TextView
android:id="@+id/loginbackbutton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="20dp"
android:layout_weight="1.7"
android:background="@drawable/backspaceimage"
android:textColor="@color/purple_700"
android:textSize="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="40dp"
android:layout_marginTop="200dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="30dp"
android:orientation="vertical">
<TextView
android:id="@+id/logintext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="회원 로그인"
android:textAlignment="center"
android:textColor="@color/purple_700"
android:textSize="25dp"
android:textStyle="bold" />
<EditText
android:id="@+id/my_Id"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:background="@color/white"
android:ems="10"
android:hint="아이디"
android:inputType="textEmailAddress"
android:text=""
android:textColor="@color/black"
android:textColorHint="@color/gray" />
<EditText
android:id="@+id/my_pw"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@color/white"
android:ems="10"
android:hint="비밀번호"
android:inputType="textPassword"
android:textColor="@color/black"
android:textColorHint="@color/gray" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/loginbutton"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:background="@drawable/cate_button_selector"
android:text="로그인"
android:textColor="@color/white"
android:textSize="13sp"
android:textStyle="bold" />
<TextView
android:id="@+id/signin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="회원가입"
android:textColor="@color/black"
android:textSize="13dp"
android:textStyle="bold" />
</LinearLayout>
</FrameLayout>
실제로 코드로 구현된 화면이다.
로그인 버튼을 눌렀을 때 위의 공식문서에서의 코드를 바탕으로 EditText의 값을 받아와서 함수에 넣어주면 된다.
public void onClick(View view) {
String email=my_Id.getText().toString();
String password=my_pw.getText().toString();
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(Login.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(Login.this,"로그인 성공",Toast.LENGTH_LONG).show();
FirebaseUser user = mAuth.getCurrentUser();
Intent intent=new Intent(getApplicationContext(),HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);//액티비티 스택제거
startActivity(intent);
} else {
Toast.makeText(Login.this, "로그인 실패", Toast.LENGTH_SHORT).show();
}
}
});
}
3)리뷰 및 좋아요
사실 리뷰 및 좋아요 기능을 구현하려고 할 때 어려웠던 점이 리뷰가 삭제도 가능해야하고 각 관광지의 리뷰와 각 유저간의 리뷰도 구분하여 가져올 수 있어야 하는데 어떻게 구현해야할 지 방식이 생각이 잘 나지않았다. 여러번의 시도 끝에 나는 Firestore에서 문서를 삭제할 때 문서의 ID가 있어야 되기 때문에 리뷰를 저장할 때 생성과 동시에 저장된 리뷰데이터를 불러올 때 문서의 아이디를 저장해주는 방식으로 구현하였고 유저, 관광지 구분을 위해 관광지 이름과 유저의 이메일도 같이 저장하였다.
처음으로 리뷰가 보이게될 틀이 될 xml을 구현해 보았다. 이 리뷰페이지는 관광지 이름을 위에 띄우고 리스트뷰로 리뷰가 리스트형태로 유동적으로 나올 수 있게 만들었다. 그리고 제일 밑에는 리뷰를 작성할 수있게 EditText, 저장할 수 있게 버튼을 붙여 주었다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="false"
android:background="#FFFFF0"
android:orientation="vertical"
android:verticalScrollbarPosition="left">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/cityName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/gray"
android:gravity="center"
android:text="관광지 이름"
android:textColor="#000000"
android:textSize="34sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/routeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<ListView
android:id="@+id/review_rlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<EditText
android:id="@+id/reviewtextbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:hint="여기에 리뷰를 작성해 주세요"
android:inputType="text"
android:padding="15dp"
android:textColor="#000000"
android:textColorHint="#8B000000" />
<Button
android:id="@+id/reviewbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollIndicators="none"
android:text="등록"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
실제로 구현된 화면이다.
등록버튼을 눌렀을 때 로그인이 돼있는 경우 로그인된 유저의 정보를 Firebaseuser 을 통해 받아온 다음 EditText에 있는 값을 받아오고 유저이메일과 관광지이름을 FireStore에 저장해주면 된다.
user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
Toast.makeText(getApplicationContext(),"로그인을 하세요",Toast.LENGTH_LONG).show();
Intent go_intent=new Intent(ReviewActivity.this, Login.class);
startActivity(go_intent);
} else {
String email=user.getEmail();
reviewtextbox=findViewById(R.id.reviewtextbox);
Map<String, Object> adddata = new HashMap<>();
adddata.put("review_text", reviewtextbox.getText().toString());
adddata.put("user_email",email);
adddata.put("con_name",name);
db.collection("Review_Data")
.add(adddata)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText(getApplicationContext(),"리뷰등록완료!",Toast.LENGTH_LONG).show();
review.clear();
db.collection("Review_Data")
.whereEqualTo("con_name",name)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
adddata.put("document_id",documentReference.getId());
db.collection("Review_Data").document(documentReference.getId())
.set(adddata)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});
for (QueryDocumentSnapshot document : task.getResult()) {
review.add(document.get("review_text",String.class));
}
ReviewListAdapter=new List_Adapter_Review(ReviewActivity.this,review);
review_List.setAdapter(ReviewListAdapter);
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
}
'Project > 경남드리' 카테고리의 다른 글
[Android][JAVA]2장. 경남드리 (0) | 2023.10.18 |
---|---|
1장. 학기에서 공모전으로 (4) | 2023.10.17 |
0장. 시작 (0) | 2023.10.17 |