Andorid

[Android]Firebase로 채팅 앱 만들기(3)

CoBool 2022. 3. 31. 14:53

지난 페이지에서는 채팅 앱에서 참여할 사용자를 추가할 수 있는 회원가입 화면을 만들어보았다.

이제는 만들어진 회원의 계정으로 로그인할 수 있는 로그인 페이지를 만들어야 한다.

먼저 로그인 레이아웃을 만들어준다.

<?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:background="#3660DC">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.6"
        app:layout_constraintStart_toStartOf="parent">

        <EditText
            android:id="@+id/edt_email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:ems="10"
            android:hint="Email"
            android:inputType="textPersonName"
            android:textColor="@color/black"
            android:textColorHint="#B8B8B8"
            app:layout_constraintBottom_toTopOf="@id/edt_password"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="packed" />

        <EditText
            android:id="@+id/edt_password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="비밀번호"
            android:inputType="textPersonName|textPassword"
            android:textColor="@color/black"
            android:textColorHint="#B8B8B8"
            app:layout_constraintBottom_toTopOf="@id/btn_sign_in"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.502"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edt_email" />

        <Button
            android:id="@+id/btn_signup"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="회원가입"
            android:textColor="@color/white"
            app:backgroundTint="#3660DC"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="@+id/edt_password"
            app:layout_constraintStart_toStartOf="@+id/edt_password"
            app:layout_constraintTop_toBottomOf="@id/btn_sign_in" />

        <Button
            android:id="@+id/btn_sign_in"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="로그인"
            android:textColor="@color/white"
            app:backgroundTint="#3660DC"
            app:layout_constraintBottom_toTopOf="@id/btn_signup"
            app:layout_constraintEnd_toEndOf="@+id/edt_password"
            app:layout_constraintStart_toStartOf="@+id/edt_password"
            app:layout_constraintTop_toBottomOf="@id/edt_password" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ChatingApp"
        android:textColor="#FFFFFF"
        android:textSize="60dp"
        app:layout_constraintBottom_toTopOf="@+id/constraintLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

로그인 레이아웃 xml은 위와 같다.

package com.miso.chatapplication

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
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.firebase.auth.AuthResult
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.miso.chatapplication.databinding.ActivityLoginBinding
import com.miso.chatapplication.main.MainActivity

class LoginActivity : AppCompatActivity() {
    lateinit var auth: FirebaseAuth
    lateinit var btn_signUp: Button
    lateinit var btn_signIn: Button
    lateinit var edt_email: EditText
    lateinit var edt_password: EditText
    lateinit var binding: ActivityLoginBinding
    lateinit var preference: SharedPreferences
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initProperty()
        initializeView()
        initializeListener()
    }

    fun initProperty() {    //초기 변수 세팅
        auth = FirebaseAuth.getInstance()     //Firebase 계정 관련 변수
        preference = getSharedPreferences("setting", MODE_PRIVATE)    //로그인 정보 저장용 SharedPreference
    }

    fun initializeView() {   //뷰 초기화
        btn_signUp = binding.btnSignup
        btn_signIn = binding.btnSignIn
        edt_email = binding.edtEmail
        edt_password = binding.edtPassword

        edt_email.setText(preference.getString("email", ""))     //마지막으로 로그인 한 이메일 세팅
        edt_password.setText(preference.getString("password", ""))   //마지막으로 로그인 한 패스워드 세팅
    }

    fun initializeListener() {        //버튼 클릭 시 리스너 세팅
        btn_signIn.setOnClickListener()
        {
            signInWithEmailAndPassword()
        }
        btn_signUp.setOnClickListener()
        {
            startActivity(Intent(this, SignUpActivity::class.java))
        }
    }

    fun signInWithEmailAndPassword() {
        if (edt_email.text.toString().isNullOrBlank() &&   //아이디 또는 패스워드가 입력되었는 지 유효성 검사
            edt_password.text.toString().isNullOrBlank())
            Toast.makeText(this, "아이디 또는 패스워드를 입력해주세요", Toast.LENGTH_SHORT).show()
        else {
            auth.signInWithEmailAndPassword(edt_email.text.toString(), edt_password.text.toString())    //로그인 실행
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Log.d("로그인", "성공")
                        val user = auth.currentUser
                        updateUI(user)
                        finish()
                    } else {
                        Toast.makeText(this, "로그인에 실패하였습니다.", Toast.LENGTH_SHORT).show()
                    }
                }
        }
    }

    private fun updateUI(user: FirebaseUser?) { //로그인 성공 시 화면 이동
        if (user != null) {
            try {
                var preference = getSharedPreferences("setting", MODE_PRIVATE).edit()    //이메일 및 패스워드 저장
                preference.putString("email", edt_email.text.toString())
                preference.putString("password", edt_password.text.toString())
                preference.apply()
                val intent = Intent(this, MainActivity::class.java)
                startActivity(intent)
                finish()
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "로그인에 실패하였습니다.", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

로그인 액티비티의 전체 코드는 위와 같다.

fun signInWithEmailAndPassword() {
        if (edt_email.text.toString().isNullOrBlank() &&   //아이디 또는 패스워드가 입력되었는 지 유효성 검사
            edt_password.text.toString().isNullOrBlank())
            Toast.makeText(this, "아이디 또는 패스워드를 입력해주세요", Toast.LENGTH_SHORT).show()
        else {
            auth.signInWithEmailAndPassword(edt_email.text.toString(), edt_password.text.toString())    //로그인 실행
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Log.d("로그인", "성공")
                        val user = auth.currentUser
                        updateUI(user)
                        finish()
                    } else {
                        Toast.makeText(this, "로그인에 실패하였습니다.", Toast.LENGTH_SHORT).show()
                    }
                }
        }
    }

로그인 버튼을 누를 시 실행되는 로그인 요청 코드이다.

이전 회원가입과 같이 firebase authentification에 접근하기 위하여

auth = FirebaseAuth.getInstance()

를 사용하여 auth 변수를 초기화 해준후,

auth.signInWithEmailAndPassword(edt_email.text.toString(), edt_password.text.toString())    //로그인 실행
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Log.d("로그인", "성공")
                        val user = auth.currentUser
                        updateUI(user)
                        finish()
                    } else {
                        Toast.makeText(this, "로그인에 실패하였습니다.", Toast.LENGTH_SHORT).show()
                    }
                }

위 함수를 사용하여 로그인을 요청한다.

회원가입 코드와 마찬가지로 task.isSuccessful로 성공 여부를 구분하며,

성공 시 다음 화면으로 진입하게 해주는 코드를 넣으면 된다.

private fun updateUI(user: FirebaseUser?) { //로그인 성공 시 화면 이동
        if (user != null) {
            try {
                var preference = getSharedPreferences("setting", MODE_PRIVATE).edit()    //이메일 및 패스워드 저장
                preference.putString("email", edt_email.text.toString())
                preference.putString("password", edt_password.text.toString())
                preference.apply()
                val intent = Intent(this, MainActivity::class.java)
                startActivity(intent)
                finish()
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "로그인에 실패하였습니다.", Toast.LENGTH_SHORT).show()
            }
        }
    }

나 같은 경우 채팅방을 보여줄 메인화면에서 사용할 주요 변수를 SharedPreference를 사용하여 저장하고,이후 이동하는 다음 액티비티에서 꺼내쓸 수 있게 하였다.

완성화면

참조

https://m.blog.naver.com/zoown13/222094002924https://cionman.tistory.com/72https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=traeumen927&logNo=221493556497https://lasbe.tistory.com/19