Firebase Tutorial Cho Android: Authentication

Trong bài viết này, mình sẽ hướng dẫn các bạn tạo một ứng dụng nho nhỏ, có sử dụng service Authentication trong Firebase. Trước khi bắt đầu đi vào chi tiết, các bạn có thể download source code tại đây

Cấu trúc project:

  • package common: có chứa các file như DialogHelpers.kt để hiển thị 1 alertdialog thông báo lỗi, ValidationHelper.kt được dùng để validate data như là email, username, password, ViewExtensions.kt dùng để xử lý các event trong UI như button click....
  • package di : chứa các set up Denpendency Injection. Ở đây chúng ta sử dụng Dagger
  • package ui: có chứa tất cả các Activity và các Fragment bạn sẽ sử dụng.
  • package model: có chứa các model class được sử dụng cho data của app.
  • package presentation và firebase: có chứa những interface và những class bạn sẽ sử dụng trong project. Trong project sử dụng mô hình MVP. Việc tổ chức project vào trong các cấu trúc package như này, làm cho project của chúng ta rõ dàng hơn.

Trong project chúng ta sẽ sử dụng email và password để xác thực người dùng. Trước khi bắt đầu, bạn cần phải add Firebase như là một dependency. Trước khi làm vậy bạn cần 1 thứ được gọi là google-service.json. Nó là một file JSON có chứa tất cả các config data mà Firebase sẽ sử dụng bên trong app. Để có được file json này, bạn cần add Firebase tới project. Click tới website của Firebase tại đây bạn sẽ nhìn thấy một vài thứ giống này:

Login sử dụng google account của bạn.Sau đó click vào button Go to Console tại góc bên phải của màn hình. Bạn bây giờ sẽ tạo một Firebase Project mới. Bạn có thể tạo nó bằng cách click trên Add projec như bên dưới.

Điền tên project mà bạn muốn và chọn quốc gia hiện tại của bạn

Chấp nhận bất kỳ điều khoản nào nếu cần thiết sau đó click Create Project. Sau khi finish bước đầu tiên, bạn sẽ thấy nhìn thấy một message thông báo success như này

Click Continue tiếp theo bạn cần add android application tới project, vậy click Add Firebase to your Android app

Điền package trong project của bạn và click Register app. Mã SHA có thể bỏ trống tại thời điểm này, bạn chỉ cần nó khi đang ký file apk. Bây giờ theo hướng dẫn trên trang Firebase để add file google-services.json tới project và click Next Tiếp theo add các libray dependencies tới module app trong file build.gradle

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.quanghoa.apps.firebase_authentication"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    kapt {
        generateStubs = true
    }
}

ext {
    supportLib = '28.0.0'
    dagger = '2.12'
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
//    support lib
    implementation "com.android.support:appcompat-v7:$supportLib"
    implementation "com.android.support:recyclerview-v7:$supportLib"
    implementation "com.android.support:cardview-v7:$supportLib"
    implementation "com.android.support:design:$supportLib"

//    DI
    implementation "com.google.dagger:dagger:$dagger"
    kapt "com.google.dagger:dagger-compiler:$dagger"

    // Firebase
    implementation 'com.google.firebase:firebase-core:16.0.1'
    implementation 'com.google.firebase:firebase-auth:16.0.2'
    implementation 'com.google.firebase:firebase-database: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'
}
apply plugin: 'com.google.gms.google-services'

và add dòng code bên dưới tới project-level build.gradle

buildscript {
  dependencies {
    //Add this line
    classpath 'com.google.gms:google-services:3.3.1'
  }
}

Sau đó sync các file gradle trong project. Bây giờ khi bạn BuildRun project, bạn sẽ nhìn thấy giao diện như này

Chúng ta sẽ có 1 màn hình Register người dùng như này:

Nó có 1 vài fields để tạo một người dùng duy nhất. Khi xây dựng một aunthentication service sử dụng email và password. người dùng cần cung cấp chúng trong khi sign up. Ngoài ra mỗi người dùng sẽ có một username. Để cho ứng dụng sử dụng email cho việc đăng ký, bạn cần enable "email sign-in'' method trong Firebase Console. Mở Firebase Console, và click trên option Authentication bên tay trái bên dưới Develop và chọn Sign-in-Method tab. Bây giờ lựa chọn Email/Passwordenable

Để kết nối aunthentication service của Firebase, đầu tiên bạn đi tới package di và tạo một class gọi là FirebaseModule.kt và cung cấp một FirebaseAuth

@Module
@Singleton
class FirebaseModule {

  @Provides
  fun firebaseAuth(): FirebaseAuth = FirebaseAuth.getInstance()

  @Provides
  fun firebaseDatabase(): FirebaseDatabase = FirebaseDatabase.getInstance()
}

Tiếp theo add module tới InteractionModule.kt

@Module(includes = [FirebaseModule::class])
@Singleton
abstract class InteractionModule { ...

Bây giờ bạn sử dụng FirebaseAuth bằng cách mở file FirebaseAuthenticationManager.kt trong package firebase.authentication và add thuộc tính FirebaseAuth tới constructor như bên dưới:

 class FirebaseAuthenticationManager @Inject constructor(
 private val authentication: FirebaseAuth) : FirebaseAuthenticationInterface

Tiếp theo sẽ override register method trong file FirebaseAuthenticationManager

override fun register(email: String, password: String, userName: String, onResult: (Boolean) -> Unit) {
        authentication.createUserWithEmailAndPassword(email, password).addOnCompleteListener {
            if (it.isComplete && it.isSuccessful) {
                authentication.currentUser?.updateProfile(
                    UserProfileChangeRequest
                        .Builder()
                        .setDisplayName(userName)
                        .build()
                )
                onResult(true)
            } else {
                onResult(false)
            }
        }
    }

Quá trình register sẽ diễn ra khi data của user là hợp lệ và user click button Sign up. Bạn sẽ tạo một user duy nhất với email được cung cấp.Nếu email đã được sử dụng, Firebase sẽ trả về một error. Nếu không một user empty sẽ được tạo. Khi bận cần một username cho user bạn mới tạo, bận cần tạo UserProfileChangeReques để edit user bao gồm một username như trong đoạn code trên.

Tiếp theo bạn sẽ chú ý, làm sao để sử dụng thuộc tính authentication.currentUser. Nó là quan trọng để biết làm thế nào FirebaseAuth service làm việc bên trong một ứng dụng android.Ngay sau khi bạn register hoặc login , currentUser là sẵn sàng for bạn sử dụng. Vê cơ bản Firebase cache lại thông tin đó cho đến khi bạn logout hoặc clear data của ứng dụng. Đây được gọi là một Session. Mặc dù không hiển thị trong code nhưng nó tồn tại cho đến khi bạn close nó.Sau khi bạn login, currentUser có chứa các thông tin như là id, email, username chúng khá tiện dụng khi bạn cần dùng tới. Kết thúc FirebaseAuthenticationManager.kt chúng ta sẽ điền phần còn lại của các method như bên dưới:

override fun login(email: String, password: String, onResult: (Boolean) -> Unit) {
    authentication.signInWithEmailAndPassword(email, password).addOnCompleteListener {
    onResult(it.isComplete && it.isSuccessful)
  }
}

override fun getUserId(): String = authentication.currentUser?.uid ?: ""
override fun getUserName(): String = authentication.currentUser?.displayName ?: ""

override fun logOut(onResult: () -> Unit) {
  authentication.signOut()

  onResult()
}

Đoạn code trên khá đơn giản. Method getUserIdgetUserName trả về data từ user hiện tại. Tiếp theo method logout đóng Session hiện tại .

Để có thể hiểu rõ dàng hơn các bạn có thể dowload đầy đủ source code tại đây