Android中使用Firebase的E-mail登入功能教學 (三)

Android中使用Firebase的E-mail登入功能教學 (三)

[新版] 在新版Android Studio 2.2整合了Firebase功能,並提供更方便的方法導入與設計,可參考:

使用Android Studio 2.2.2 開發Firebase – Database篇

使用Android Studio 2.2.2 開發Firebase – E-mail 登入篇

使用Android Studio 2.2.2 開發Firebase – Database篇 part2


Firebase支援許多種類的帳號驗證功能,不論在開發Android或iOS的應用程式時都能很快能夠提供會員登入、驗證功能,省去了建置後台會員資料庫、系統程式的繁複過程。本篇將介紹如何能夠以Email電子郵件與密碼實作登入功能,快速開發一個具會員登入驗證的Android應用程式。

本篇是延續之前兩篇文章,請參考:

1. 在Android中使用2016新版Firebase加快開發過程(一)

2. 在Android中使用2016新版Firebase加快開發過程(二)

 

啟用Firebase的E-mail帳號驗證功能

首先,請在Firebase的網站控制台中的左方功能表點擊「Auth」登入與認證功能,如下圖:

A6093-n

再點擊功能上方的「登入方式」頁籤後,點擊「Email/Password」並啟用Email與密碼驗證功能,最後按下儲存,如下圖:

A6096

此步驟已啟用本Firebase專案啟用Email驗證帳號的功能。

手動建立帳號

請點擊上方「使用者」頁籤,並按下「新增使用者」先手動建立測試專用的Email帳號,如下圖:

A6097_n

再輸入自己能夠收到信件的Email與自行設定密碼(如112233),以建立一個測試帳號:

A6098_n

按下上圖的「新增使用者」,以建立該試帳號,如下圖:

A6099_n

登入畫面實作

接下來為應用程式建立一個登入畫面,請點擊app模組後,使用功能表File/New/Activity/Empty Activity,建立一個新的空白Activity,名稱為LoginActivity,並勾選其成為啟動用的Activity如下圖:

A4629_n

為了讓LoginActivity成為應用程式啟用的Activity,請打開AndroidManifest.xml,將原MainActivity內的intent-filter刪除,保留LoginActivity內的啟用元素,如下:

A4632_n

1. 設計登入畫面

請開啟「activity_login.xml」,並設計如下圖的登入版面:

A6100

「res/layout/activity_login.xml」的原始碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.tom.firechat.LoginActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Email"
        android:id="@+id/textView2" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/email"
        android:inputType="textEmailAddress" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Password"
        android:id="@+id/textView3" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/password"
        android:inputType="textPassword" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="LOGIN"
        android:id="@+id/button"
        android:layout_gravity="center_horizontal"
        android:onClick="login" />
</LinearLayout>

2. 登入程式設計

請開啟LoginActivity,進行登入功能程式設計先在類別中新增一個FirebaseAuth類別的屬性auth,並在onCreate方法中呼叫FirebaseAuth類別方法getInstance取得物件參照,如下:

public class LoginActivity extends AppCompatActivity {
    FirebaseAuth auth;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        auth = FirebaseAuth.getInstance();
    }
    ...
}

為了在未來登入後得到成功或失敗的狀態,再新增一個實作FirebaseAuth.AuthStateListener介面的屬性authListener,並在onCreate方法中實作該介面,以下程式碼的import語法為:

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

程式碼:

public class LoginActivity extends AppCompatActivity {
    FirebaseAuth auth;
    FirebaseAuth.AuthStateListener authListener;
    private String userUID;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        auth = FirebaseAuth.getInstance();
        authListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(
                    @NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user!=null) {
                    Log.d("onAuthStateChanged", "登入:"+
                            user.getUid());
                    userUID =  user.getUid();
                }else{
                    Log.d("onAuthStateChanged", "已登出");
                }
            }
        };
    }
}

authListener屬性是能夠在帳號登入或登出時擷取狀態的事件傾聽器,會自動呼叫第13-23行的onAuthStateChanged方法,並得到一個FirebaseAuth的驗證物件firebaseAuth。

第14行,呼叫FirebaseAuth類別的getCurrentUser方法可取得目前登入的使用者物件user。

第16-20行,若取得user物件不是null,代表登入成功。

第19行,將帳號的UID儲存在userUID屬性,本章後續功能會使用到它。

第21行,若取得user物件是null,代表使用者登出。

接下來,請覆寫LoginActivity的onStart與onStop方法(快速鍵Ctrl+O),實作以下程式碼:

@Override
protected void onStart() {
    super.onStart();
    auth.addAuthStateListener(authListener);
}

@Override
protected void onStop() {
    super.onStop();
    auth.removeAuthStateListener(authListener);
}

第4行,呼叫addAuthStateListener方法加入傾聽器屬性,每次LoginActivity首次顯示或是從背景返回前景時都會自動開始傾聽事件。

第10行,呼叫removeAuthStateListener方法移除傾聽事件,每次LoginActivity進入背景或結束時都會停止傾聽事件。

接著在LoginActivity中新增一個方法login,傳入參數為android.widget.View,並實作以下登入程式碼:

public void login(View v){
    String email = ((EditText)findViewById(R.id.email))
            .getText().toString();
    String password = ((EditText)findViewById(R.id.password))
            .getText().toString();
    Log.d("AUTH", email+"/"+password);
    auth.signInWithEmailAndPassword(email, password);
}

第2-3行,取得畫面輸入的Email字串資料。

第4-5行,取得畫面輸入的密碼字串資料。

第7行,呼叫FirebaseAuth類別的signInWithEmailAndPassword方法進行帳號與密碼的登入。

執行專案後,出現登入畫面,請輸入剛才建立的測試Email帳號與密碼,如下圖:

A6101

程式已由Firebase雲端應用程式中完成帳號驗證,回傳該帳號的「User ID」,LogCat的除錯內容顯示如下:

D/AUTH: hanktom881@gmail.com/112233
D/FirebaseAuth: Notifying listeners about user ( 略 ).
D/FirebaseApp: Notifying auth state listeners.
D/FirebaseApp: Notified 0 auth state listeners.
D/onAuthStateChanged: 登入:vOfOPBkOO6OAZ8fyyIcOuznT1lh1
D/FirebaseAuth: Notifying listeners about user ( 略 ).
D/FirebaseApp: Notifying auth state listeners.
D/FirebaseApp: Notified 0 auth state listeners.

上述LogCat顯示登入成功時的訊息與該使用者的UID值。使用Firebase的帳號驗證API,可以讓我們省去開發、架設伺服端程式,也不需要建置後台資料庫與表格等,以快速、簡易的方式達到帳號驗證的功能。

本階段完成的程式碼為

檔案庫(Repository): https://github.com/android66/FireChat.git

版本名稱: Email與密碼登入實作

註: 請在取得專案後, 一定要置換讀者自己環境所產生的 google-services.json檔, 才能正常運作。

下一篇將介紹Firebase的簡易E-mail註冊功能:

使用Firebase的Email註冊功能實作Android APP(四)

相關文章:

Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 , 為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

This Post Has 11 Comments

  1. Avatar

    感謝作者文章,受益良多. 中文網路資訊目前很少.
    希望可以多一些firebase中文教學^.^

  2. Avatar

    根據你的教學實作後,log會噴出error如下,您的code也會.
    E/DynamiteModule: Failed to load module descriptor class: Didn’t find class “com.google.android.gms.dynamite.descriptors.com.google.firebase.auth.ModuleDescriptor”
    on path: DexPathList[[zip file “/data/app/shay.murray.firebasetest-1/base.apk”],nativeLibraryDirectories=[/data/app/shay.murray.firebasetest-1/lib/arm64, /vendor/lib64, /system/lib64]]

    請問是什麼原因呢?!

    1. Avatar

      您說的是在LogCat中有額外的Error訊息,但APP執行是正常的,由Firebase官方人士表示那是因為Google Play Services的一個bug,導致它的類別庫將除錯訊息用Error層級印出,可以不理會它,官方會在下次改版時修正。

      1. Avatar

        瞭解,感謝您回答.

  3. Avatar

    Android 6.0進階系列課程—Firebase整合實務應用
    不知道可否把7/23(六)上課時間再往前調整嗎?
    因衝突,方才可以上課!

    1. Avatar

      我會請課程規劃人與您e-mail聯繫

  4. Avatar

    請問我都會跑出這個error,不知道是我哪裡沒有弄好嗎
    上網找找不太到解決辦法
    Error:(22, 28) error: cannot access zzaja
    class file for com.google.android.gms.internal.zzaja not found

    1. Avatar

      資訊不大夠,但昨天有發生類似的問題,可以試著開啟build.gradle(Module:app),再將support-v7的版本由24改為23後試看看。

      1. Avatar

        謝謝您的回答
        我將版本修改之後問題已解決
        謝謝您

  5. Avatar

    Error:(22, 28) error: cannot access zzbql
    class file for com.google.android.gms.internal.zzbql not found
    Build APK的時候出現的錯誤訊息
    想請問如何修改

    1. Avatar

      這類問題通常是Google Play Services版本不符,模擬器常出現這個問題,請改用有Play商店的模擬器或用實體手機試試

發佈留言

×
×

Cart