在 Android 上使用 Facebook 登入進行驗證

將 Facebook 登入功能整合至應用程式中,即可讓使用者利用自己的 Facebook 帳戶使用 Firebase 進行驗證。

事前準備

  1. 如果您尚未將 Firebase 新增至 Android 專案,請先完成這項作業。

  2. Facebook for Developers 網站上,取得應用程式的應用程式 ID應用程式密鑰
  3. 啟用 Facebook 登入功能:
    1. Firebase 控制台,開啟「Auth」(驗證) 區段。
    2. 在「Sign in method」分頁中,啟用「Facebook」登入方法,並指定您從 Facebook 取得的「App ID」和「App Secret」
    3. 接著,前往 Facebook 應用程式的「Facebook for Developers」網站 (依序前往「Product Settings」>「Facebook Login」設定),確認 OAuth 重新導向 URI (例如 my-app-12345.firebaseapp.com/__/auth/handler) 列為其中一個 OAuth 重新導向 URI
  4. 模組 (應用程式層級) Gradle 檔案 (通常是 <project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle) 中,新增 Android 適用的 Firebase 驗證程式庫的依附元件。建議您使用 Firebase Android BoM 來控管程式庫版本管理。

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    }
    

    如果使用 Firebase Android BoM,應用程式就會一律使用相容的 Firebase Android 程式庫版本。

    (替代方法) 新增 Firebase 程式庫依附元件,「不必」使用 BoM

    如果選擇不使用 Firebase BoM,請務必在依附元件行中指定各個 Firebase 程式庫版本。

    請注意,如果在應用程式中使用多個 Firebase 程式庫,強烈建議您使用 BoM 管理程式庫版本,確保所有版本都相容。

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.0.0")
    }
    
    在尋找 Kotlin 專用的程式庫模組嗎?2023 年 10 月 (Firebase BoM 32.5.0) 起,Kotlin 和 Java 開發人員都可以依賴主程式庫模組 (詳情請參閱這項計畫的常見問題)。

使用 Firebase 進行驗證

  1. 按照 開發人員說明文件的說明,將 Facebook 登入功能整合到您的應用程式。當您設定 LoginButtonLoginManager 物件時,請要求 public_profileemail 權限。如果您使用 LoginButton 整合 Facebook 登入,您的登入活動程式碼會與下列程式碼類似:

    Kotlin+KTX

    // Initialize Facebook Login button
    callbackManager = CallbackManager.Factory.create()
    
    buttonFacebookLogin.setReadPermissions("email", "public_profile")
    buttonFacebookLogin.registerCallback(
        callbackManager,
        object : FacebookCallback<LoginResult> {
            override fun onSuccess(loginResult: LoginResult) {
                Log.d(TAG, "facebook:onSuccess:$loginResult")
                handleFacebookAccessToken(loginResult.accessToken)
            }
    
            override fun onCancel() {
                Log.d(TAG, "facebook:onCancel")
            }
    
            override fun onError(error: FacebookException) {
                Log.d(TAG, "facebook:onError", error)
            }
        },
    )
    // ...
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    
        // Pass the activity result back to the Facebook SDK
        callbackManager.onActivityResult(requestCode, resultCode, data)
    }

    Java

    // Initialize Facebook Login button
    mCallbackManager = CallbackManager.Factory.create();
    LoginButton loginButton = findViewById(R.id.button_sign_in);
    loginButton.setReadPermissions("email", "public_profile");
    loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            Log.d(TAG, "facebook:onSuccess:" + loginResult);
            handleFacebookAccessToken(loginResult.getAccessToken());
        }
    
        @Override
        public void onCancel() {
            Log.d(TAG, "facebook:onCancel");
        }
    
        @Override
        public void onError(FacebookException error) {
            Log.d(TAG, "facebook:onError", error);
        }
    });
    // ...
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        // Pass the activity result back to the Facebook SDK
        mCallbackManager.onActivityResult(requestCode, resultCode, data);
    }
  2. 在登入活動的 onCreate 方法中,取得 FirebaseAuth 物件的共用例項:

    Kotlin+KTX

    private lateinit var auth: FirebaseAuth
    // ...
    // Initialize Firebase Auth
    auth = Firebase.auth

    Java

    private FirebaseAuth mAuth;
    // ...
    // Initialize Firebase Auth
    mAuth = FirebaseAuth.getInstance();
  3. 初始化活動時,請檢查使用者是否已登入:

    Kotlin+KTX

    public override fun onStart() {
        super.onStart()
        // Check if user is signed in (non-null) and update UI accordingly.
        val currentUser = auth.currentUser
        updateUI(currentUser)
    }

    Java

    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.
        FirebaseUser currentUser = mAuth.getCurrentUser();
        updateUI(currentUser);
    }
  4. 使用者成功登入後,請在 LoginButtononSuccess 回呼方法中取得已登入使用者的存取權杖、交換 Firebase 憑證,然後使用 Firebase 憑證向 Firebase 進行驗證:

    Kotlin+KTX

    private fun handleFacebookAccessToken(token: AccessToken) {
        Log.d(TAG, "handleFacebookAccessToken:$token")
    
        val credential = FacebookAuthProvider.getCredential(token.token)
        auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCredential:success")
                    val user = auth.currentUser
                    updateUI(user)
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    Toast.makeText(
                        baseContext,
                        "Authentication failed.",
                        Toast.LENGTH_SHORT,
                    ).show()
                    updateUI(null)
                }
            }
    }

    Java

    private void handleFacebookAccessToken(AccessToken token) {
        Log.d(TAG, "handleFacebookAccessToken:" + token);
    
        AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
        mAuth.signInWithCredential(credential)
                .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, "signInWithCredential:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(FacebookLoginActivity.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                            updateUI(null);
                        }
                    }
                });
    }
    如果呼叫 signInWithCredential 成功,您可以使用 getCurrentUser 方法取得使用者的帳戶資料。

後續步驟

使用者首次登入後,系統會建立新的使用者帳戶,並連結至用來登入的使用者憑證,也就是使用者名稱與密碼、電話號碼或驗證提供者資訊。這個新帳戶以 Firebase 專案的形式儲存,無論使用者以何種方式登入,都能從專案中的每個應用程式識別使用者。

  • 在應用程式中,您可以從 FirebaseUser 物件取得使用者的基本個人資料。請參閱「 管理使用者」一文。

  • 在 Firebase 即時資料庫和 Cloud Storage 安全性規則中,您可以從 auth 變數取得已登入使用者的專屬 ID,並使用該 ID 控管使用者可存取的資料。

您可以將驗證提供者憑證連結至現有的使用者帳戶,讓使用者透過多個驗證提供者登入您的應用程式。

如要登出使用者,請呼叫 signOut

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();