Firebase로 안드로이드 SNS 앱 만들기 - 01 안드로이드 스튜디오 시작하기

출처

하울, 『Firebase로 안드로이드 SNS 앱 만들기』, 비제이퍼블릭(2018-07-31), 8-43p


안드로이드 프로젝트 및 Firebase 연동

  • google-services.json 파일 필요
  • Gradle에 직접 설정하는 법과 Assistant로 설정하는 방법이 있는데 Assistant로 하기

Assistant로 설정하는 방법

  1. Tools –> Firebase Assistant
  2. Authentication 클릭
  3. 클릭하면 번호대로 설명 나오고 다 수행하면 완료

image


라이브러리 사용하기

  • Firebase 콘솔에 들어가면 안드로이드 프로젝트와 같은 이름의 프로젝트가 존재하는데 들어가서 개발 –> Authentication에서 이메일 사용 설정
  • Firebase 콘솔에서 설정이 완료되었으면 MainActivity.kt에 이메일 로그인과 관련한 변수 및 함수 호출 코드를 삽입
  • 꿀팁: 코드정렬은 ctrl+L, 문제 해결 제안은 ctrl+enter
  • 꿀팁2: build.gradle(Project), build.gradle(Module)에서 형광펜으로 하이라이트 되어 있으면 전부 ctrl+L을 눌러 버전 높이기

image

1. FirebaseAuth 호출 코드 삽입

var auth : FirebaseAuth?= null
auth = FirebaseAuth.getInstance()

2. 회원 가입 코드 삽입

fun createUserId(email: String, password: String) {
        auth?.createUserWithEmailAndPassword(email, password)
            ?.addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // 아이디 생성이 완료되었을 때
                    val user = auth?.getCurrentUser()

                } else { // 아이디 생성이 실패했을 경우
                    Toast.makeText(this, "아이디 생성 실패", Toast.LENGTH_SHORT).show()
                }
            }
    }

3. 로그인 코드 삽입

fun loginUserId(email: String, password: String) {
        auth?.signInWithEmailAndPassword(email, password)
            ?.addOnCompleteListener(this) { task ->
                if (task.isSuccessful) { // 로그인 성공 시 이벤트 발생
                    Toast.makeText(this, "로그인 성공", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "로그인 실패", Toast.LENGTH_SHORT).show()
                }
            }
    }

4. 메일 유효성 체크 코드 삽입

fun verifyEmail() {
        auth?.currentUser?.sendEmailVerification()
            ?.addOnCompleteListener { task ->
                if(task.isSuccessful) {
                    Toast.makeText(this, "유효성 체크 됨", Toast.LENGTH_LONG).show()
                }
            }
    }
  • 이메일 인증 메일 내용은 수정 불가 제목은 가능 Firebase 콘솔에서 진행하면 됨

5. 패스워드 변경 코드 삽입

fun updatePassword(newPassword:String) {
        auth?.currentUser?.updatePassword(newPassword)

            ?.addOnCompleteListener {task ->
                if(task.isSuccessful)
                    Toast.makeText(this, "패스워드 변경 성공", Toast.LENGTH_LONG).show()
            }
    }

6. 아이디 변경 코드 삽입

fun updateEmail(newEmail: String) {
        auth?.currentUser?.updateEmail(newEmail)
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "이메일 변경 성공", Toast.LENGTH_LONG).show()
                }
            }
    }
}

7. 비밀번호 재설정 코드 삽입

fun resetPassword(email : String) {
        auth?.sendPasswordResetEmail(email)
            ?.addOnCompleteListener { task ->
                if(task.isSuccessful) {
                    Toast.makeText(this, "비밀번호 재설정 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

8. 회원 탈퇴 코드 삽입

fun deleteId() {
        auth?.currentUser?.delete()
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "회원 아이디 삭제 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

9. 회원 재인증 코드 삽입

fun reauthenticate(email: String, password: String) {
        val credential = EmailAuthProvider
            .getCredential(email, password)

        auth?.currentUser?.reauthenticate(credential)
            ?.addOnCompleteListener { task: Task<Void> ->
                if (task.isComplete) {
                    Toast.makeText(this, "재인증 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

10. 로그인 되었는지 확인하는 인터페이스 코드 삽입

var authListener: FirebaseAuth.AuthStateListener? = null
authListener = FirebaseAuth.AuthStateListener { FirebaseAuth ->
            val user = FirebaseAuth.currentUser
            if (user != null) {
                Toast.makeText(this, "로그인 됨", Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(this, "로그인 안 됨", Toast.LENGTH_LONG).show()
            }
        }
override fun onStart() {
        super.onStart()
        auth?.addAuthStateListener(authListener!!)
    }

    override fun onPause() {
        super.onPause()
        auth?.removeAuthStateListener(authListener!!)
    }

구글 로그인

  • 안드로이드에서 가장 많이 쓰는 기능

1. 라이브러리 설치

  • Build.gradle(Module:app)의 dependencies에 implementation 'com.google.firebase:firebase-auth:16.1.0', implementation 'com.google.android.gms:play-services-auth:16.0.1' 삽입 후 Sync

2. 구글 로그인 클래스 만들기

var googleSignInClient: GoogleSignInClient? = null
var gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail().build()
googleSignInClient = GoogleSignIn.getClient(this, gso)

3. 구글 로그인 실행 이벤트 코드

fun signIn() {
        val signInIntent = googleSignInClient?.signInIntent
        startActivityForResult(signInIntent, 100) // request 100 입력
    }

4. 구글 로그인 결과 받는 코드

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == 100) { // requestCode : 100을 입력해준다.
            val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
            if(result.isSuccess) {
                // 구글 로그인이 성공했을 경우
                val account = result.signInAccount
                val credential = GoogleAuthProvider.getCredential(account?.idToken, null) // 로그인이 성공했을 경우 IdToken을 넘겨주고 이를 이용해 Credential 인증서를 만들어줌
                FirebaseAuth.getInstance().signInWithCredential(credential) // Credential을 Firebase에 넘겨주면 Firebase에 구글 로그인 계정이 만들어짐
            }
        }
    }

5. 구글 콘솔 설정

  • Authentication > 로그인 방법 > Google로 이동 후 사용 설정 후 저장 클릭

image


위 코드를 통합한 MainActivity.kt

package com.example.gogo2

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.gms.tasks.Task
import com.google.firebase.FirebaseApp
import com.google.firebase.auth.*

import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    var auth: FirebaseAuth? = null
    var authListener: FirebaseAuth.AuthStateListener? = null
    var googleSignInClient: GoogleSignInClient? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        auth = FirebaseAuth.getInstance()
        authListener = FirebaseAuth.AuthStateListener { FirebaseAuth ->
            val user = FirebaseAuth.currentUser
            if (user != null) {
                Toast.makeText(this, "로그인 됨", Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(this, "로그인 안 됨", Toast.LENGTH_LONG).show()
            }
        }

        var gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail().build()
        googleSignInClient = GoogleSignIn.getClient(this, gso)
    }

    override fun onStart() {
        super.onStart()
        auth?.addAuthStateListener(authListener!!)
    }

    override fun onPause() {
        super.onPause()
        auth?.removeAuthStateListener(authListener!!)
    }

    fun createUserId(email: String, password: String) {
        auth?.createUserWithEmailAndPassword(email, password)
            ?.addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // 아이디 생성이 완료되었을 때
                    val user = auth?.getCurrentUser()

                } else { // 아이디 생성이 실패했을 경우
                    Toast.makeText(this, "아이디 생성 실패", Toast.LENGTH_SHORT).show()
                }
            }
    }

    fun loginUserId(email: String, password: String) {
        auth?.signInWithEmailAndPassword(email, password)
            ?.addOnCompleteListener(this) { task ->
                if (task.isSuccessful) { // 로그인 성공 시 이벤트 발생
                    Toast.makeText(this, "로그인 성공", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "로그인 실패", Toast.LENGTH_SHORT).show()
                }
            }
    }

    fun verifyEmail() {
        auth?.currentUser?.sendEmailVerification()
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "유효성 체크 됨", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun updatePassword(newPassword: String) {
        auth?.currentUser?.updatePassword(newPassword)

            ?.addOnCompleteListener { task ->
                if (task.isSuccessful)
                    Toast.makeText(this, "패스워드 변경 성공", Toast.LENGTH_LONG).show()
            }
    }

    fun updateEmail(newEmail: String) {
        auth?.currentUser?.updateEmail(newEmail)
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "이메일 변경 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun resetPassword(email: String) {
        auth?.sendPasswordResetEmail(email)
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "비밀번호 재설정 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun deleteId() {
        auth?.currentUser?.delete()
            ?.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(this, "회원 아이디 삭제 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun reauthenticate(email: String, password: String) {
        val credential = EmailAuthProvider
            .getCredential(email, password)

        auth?.currentUser?.reauthenticate(credential)
            ?.addOnCompleteListener { task: Task<Void> ->
                if (task.isComplete) {
                    Toast.makeText(this, "재인증 성공", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun signIn() {
        val signInIntent = googleSignInClient?.signInIntent
        startActivityForResult(signInIntent, 100) // request 100 입력
    }

    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == 100) { // requestCode : 100을 입력해준다.
            val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
            if (result.isSuccess) {
                // 구글 로그인이 성공했을 경우
                val account = result.signInAccount
                val credential = GoogleAuthProvider.getCredential(
                    account?.idToken,
                    null
                ) // 로그인이 성공했을 경우 IdToken을 넘겨주고 이를 이용해 Credential 인증서를 만들어줌
                FirebaseAuth.getInstance()
                    .signInWithCredential(credential) // Credential을 Firebase에 넘겨주면 Firebase에 구글 로그인 계정이 만들어짐
            }
        }
    }
}

build.gradle(Project)

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.21'
    repositories {
        google()
        jcenter()
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.2.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle(Module)

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.gogo2"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.firebase:firebase-auth:16.1.0'
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • 페이스북, 트위터 로그인은 어차피 안 쓸거니 SKIP 헤헤

Comments