เพิ่มการลงชื่อเข้าใช้ในแอป Android ได้ง่ายๆ ด้วย FirebaseUI

FirebaseUI เป็นไลบรารีที่สร้างต่อยอดมาจาก Firebase Authentication SDK ซึ่งให้ขั้นตอน UI แบบดรอปอินสำหรับใช้ในแอป FirebaseUI มีประโยชน์ดังนี้

  • ผู้ให้บริการหลายราย - ขั้นตอนการลงชื่อเข้าใช้สำหรับอีเมล/รหัสผ่าน, ลิงก์อีเมล, การตรวจสอบสิทธิ์ทางโทรศัพท์, Google Sign-In, การเข้าสู่ระบบ Facebook, การเข้าสู่ระบบ Twitter และการเข้าสู่ระบบ GitHub
  • การจัดการบัญชี - ขั้นตอนในการจัดการงานการจัดการบัญชี เช่น การสร้างบัญชีและการรีเซ็ตรหัสผ่าน
  • การลิงก์บัญชี - ขั้นตอนในการลิงก์บัญชีผู้ใช้ข้ามผู้ให้บริการข้อมูลประจำตัวอย่างปลอดภัย
  • การอัปเกรดผู้ใช้ที่ไม่ระบุชื่อ - ขั้นตอนในการอัปเกรดผู้ใช้ที่ไม่ระบุชื่ออย่างปลอดภัย
  • ธีมที่กำหนดเอง - ปรับแต่งรูปลักษณ์ของ FirebaseUI ให้เข้ากับแอป เนื่องจาก FirebaseUI เป็นโอเพนซอร์ส คุณจึงแยกโปรเจ็กต์และปรับแต่ง ตามความต้องการได้
  • Smart Lock สำหรับรหัสผ่าน - การผสานรวมอัตโนมัติกับ Smart Lock สำหรับรหัสผ่าน เพื่อการลงชื่อเข้าใช้ข้ามอุปกรณ์ที่รวดเร็ว

ก่อนเริ่มต้น

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากยังไม่ได้ทำ

  2. เพิ่มทรัพยากร Dependency สำหรับ FirebaseUI ลงในไฟล์ build.gradle ระดับแอป หากต้องการรองรับการลงชื่อเข้าใช้ด้วย Facebook หรือ Twitter ให้รวม SDK ของ Facebook และ Twitter ไว้ด้วย ดังนี้

    dependencies {
        // ...
    
        implementation 'com.firebaseui:firebase-ui-auth:7.2.0'
    
        // Required only if Facebook login support is required
        // Find the latest Facebook SDK releases here: https://goo.gl/Ce5L94
        implementation 'com.facebook.android:facebook-android-sdk:8.x'
    }
    

    Firebase UI Auth SDK มีทรัพยากร Dependency แบบชั่วคราวใน Firebase SDK และ SDK ของบริการ Google Play

  3. ในคอนโซล Firebase ให้เปิดส่วนการตรวจสอบสิทธิ์ และเปิดใช้วิธีการลงชื่อเข้าใช้ที่คุณต้องการรองรับ วิธีการลงชื่อเข้าใช้บางวิธีจำเป็นต้องมีข้อมูลเพิ่มเติม ซึ่งโดยปกติแล้วจะอยู่ในคอนโซลนักพัฒนาของบริการ

  4. หากคุณเปิดใช้ Google Sign-In

    1. เมื่อได้รับแจ้งในคอนโซล ให้ดาวน์โหลดไฟล์การกำหนดค่า Firebase ที่อัปเดตแล้ว (google-services.json) ซึ่งตอนนี้มีข้อมูลไคลเอ็นต์ OAuth ที่จำเป็นสำหรับการลงชื่อเข้าใช้ Google แล้ว

    2. ย้ายไฟล์การกำหนดค่าที่อัปเดตนี้ไปยังโปรเจ็กต์ Android Studio โดยแทนที่ไฟล์การกำหนดค่าที่เกี่ยวข้องซึ่งล้าสมัยแล้ว (ดูเพิ่ม Firebase ในโปรเจ็กต์ Android)

    3. หากคุณยังไม่ได้ระบุลายนิ้วมือ SHA ของแอป ให้ระบุจากหน้าการตั้งค่าของคอนโซล Firebase ดูรายละเอียดเกี่ยวกับวิธีรับลายนิ้วมือ SHA ของแอปได้ที่การตรวจสอบสิทธิ์ไคลเอ็นต์

  5. หากคุณรองรับการลงชื่อเข้าใช้ด้วย Facebook หรือ Twitter ให้เพิ่มทรัพยากรสตริงลงใน strings.xml ซึ่งระบุข้อมูลที่ผู้ให้บริการแต่ละรายต้องการ ดังนี้

    
    <resources>
      <!-- Facebook application ID and custom URL scheme (app ID prefixed by 'fb'). -->
      <string name="facebook_application_id" translatable="false">YOUR_APP_ID</string>
      <string name="facebook_login_protocol_scheme" translatable="false">fbYOUR_APP_ID</string>
    </resources>
    

ลงชื่อเข้าใช้

สร้าง ActivityResultLauncher ซึ่งจะบันทึกการเรียกกลับสำหรับสัญญาผลลัพธ์ของกิจกรรม FirebaseUI

Kotlin+KTX

// See: https://developer.android.com/training/basics/intents/result
private val signInLauncher = registerForActivityResult(
    FirebaseAuthUIActivityResultContract(),
) { res ->
    this.onSignInResult(res)
}

Java

// See: https://developer.android.com/training/basics/intents/result
private final ActivityResultLauncher<Intent> signInLauncher = registerForActivityResult(
        new FirebaseAuthUIActivityResultContract(),
        new ActivityResultCallback<FirebaseAuthUIAuthenticationResult>() {
            @Override
            public void onActivityResult(FirebaseAuthUIAuthenticationResult result) {
                onSignInResult(result);
            }
        }
);

หากต้องการเริ่มลงชื่อเข้าใช้ FirebaseUI ให้สร้าง Intent ในการลงชื่อเข้าใช้ด้วยวิธีที่คุณต้องการ

Kotlin+KTX

// Choose authentication providers
val providers = arrayListOf(
    AuthUI.IdpConfig.EmailBuilder().build(),
    AuthUI.IdpConfig.PhoneBuilder().build(),
    AuthUI.IdpConfig.GoogleBuilder().build(),
    AuthUI.IdpConfig.FacebookBuilder().build(),
    AuthUI.IdpConfig.TwitterBuilder().build(),
)

// Create and launch sign-in intent
val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .build()
signInLauncher.launch(signInIntent)

Java

// Choose authentication providers
List<AuthUI.IdpConfig> providers = Arrays.asList(
        new AuthUI.IdpConfig.EmailBuilder().build(),
        new AuthUI.IdpConfig.PhoneBuilder().build(),
        new AuthUI.IdpConfig.GoogleBuilder().build(),
        new AuthUI.IdpConfig.FacebookBuilder().build(),
        new AuthUI.IdpConfig.TwitterBuilder().build());

// Create and launch sign-in intent
Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .build();
signInLauncher.launch(signInIntent);

เมื่อขั้นตอนการลงชื่อเข้าใช้เสร็จสิ้นแล้ว คุณจะได้รับผลลัพธ์ใน onSignInResult:

Kotlin+KTX

private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
    val response = result.idpResponse
    if (result.resultCode == RESULT_OK) {
        // Successfully signed in
        val user = FirebaseAuth.getInstance().currentUser
        // ...
    } else {
        // Sign in failed. If response is null the user canceled the
        // sign-in flow using the back button. Otherwise check
        // response.getError().getErrorCode() and handle the error.
        // ...
    }
}

Java

private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
    IdpResponse response = result.getIdpResponse();
    if (result.getResultCode() == RESULT_OK) {
        // Successfully signed in
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        // ...
    } else {
        // Sign in failed. If response is null the user canceled the
        // sign-in flow using the back button. Otherwise check
        // response.getError().getErrorCode() and handle the error.
        // ...
    }
}

ตั้งค่าวิธีการลงชื่อเข้าใช้

  1. ในคอนโซล Firebase ให้เปิดส่วนการตรวจสอบสิทธิ์ ในแท็บวิธีการลงชื่อเข้าใช้ ให้เปิดใช้ผู้ให้บริการอีเมล/รหัสผ่าน โปรดทราบว่า คุณต้องเปิดใช้งานการลงชื่อเข้าใช้อีเมล/รหัสผ่านเพื่อใช้การลงชื่อเข้าใช้ด้วยลิงก์อีเมล

  2. ในส่วนเดียวกันนี้ ให้เปิดใช้วิธีการลงชื่อเข้าใช้ลิงก์อีเมล (ลงชื่อเข้าใช้แบบไม่ต้องใช้รหัสผ่าน) แล้วคลิกบันทึก

  3. นอกจากนี้คุณจะต้องเปิดใช้ลิงก์แบบไดนามิกของ Firebase เพื่อใช้การลงชื่อเข้าใช้ด้วยลิงก์อีเมล ในคอนโซล Firebase ให้คลิกลิงก์แบบไดนามิก ในส่วนมีส่วนร่วมในแถบนำทาง คลิกเริ่มต้นใช้งานและเพิ่มโดเมน โดเมนที่คุณเลือกที่นี่จะปรากฏในลิงก์อีเมลที่ส่งไปยังผู้ใช้ของคุณ

  4. คุณเปิดใช้การลงชื่อเข้าใช้ลิงก์อีเมลใน FirebaseUI ได้โดยเรียกใช้ enableEmailLinkSignIn บนอินสแตนซ์ EmailBuilder นอกจากนี้ คุณจะต้องระบุออบเจ็กต์ ActionCodeSettings ที่ถูกต้องพร้อม setHandleCodeInApp ที่ตั้งค่าเป็น "จริง" นอกจากนี้ คุณต้องเพิ่ม URL ที่ส่งไปยัง setUrl ในรายการที่อนุญาตพิเศษ ซึ่งทำได้ในคอนโซล Firebase ในส่วนการตรวจสอบสิทธิ์ -> วิธีลงชื่อเข้าใช้ -> โดเมนที่ได้รับอนุญาต

    Kotlin+KTX

    val actionCodeSettings = ActionCodeSettings.newBuilder()
        .setAndroidPackageName( // yourPackageName=
            "...", // installIfNotAvailable=
            true, // minimumVersion=
            null,
        )
        .setHandleCodeInApp(true) // This must be set to true
        .setUrl("https://google.com") // This URL needs to be whitelisted
        .build()
    
    val providers = listOf(
        EmailBuilder()
            .enableEmailLinkSignIn()
            .setActionCodeSettings(actionCodeSettings)
            .build(),
    )
    val signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .build()
    signInLauncher.launch(signInIntent)

    Java

    ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder()
            .setAndroidPackageName(
                    /* yourPackageName= */ "...",
                    /* installIfNotAvailable= */ true,
                    /* minimumVersion= */ null)
            .setHandleCodeInApp(true) // This must be set to true
            .setUrl("https://google.com") // This URL needs to be whitelisted
            .build();
    
    List<AuthUI.IdpConfig> providers = Arrays.asList(
            new AuthUI.IdpConfig.EmailBuilder()
                    .enableEmailLinkSignIn()
                    .setActionCodeSettings(actionCodeSettings)
                    .build()
    );
    Intent signInIntent = AuthUI.getInstance()
            .createSignInIntentBuilder()
            .setAvailableProviders(providers)
            .build();
    signInLauncher.launch(signInIntent);
  5. หากต้องการดูลิงก์ในกิจกรรมใดกิจกรรมหนึ่ง โปรดทำตามขั้นตอนที่ระบุไว้ที่นี่ มิเช่นนั้น ลิงก์จะเปลี่ยนเส้นทางไปยังกิจกรรมของ Launcher

  6. เมื่อเจอ Deep Link แล้ว คุณจะต้องโทรเพื่อยืนยันว่าเราจัดการ Deep Link ให้คุณได้ ถ้าทำได้ คุณต้องส่งมาให้เราผ่าน setEmailLink

    Kotlin+KTX

    if (AuthUI.canHandleIntent(intent)) {
        val extras = intent.extras ?: return
        val link = extras.getString("email_link_sign_in")
        if (link != null) {
            val signInIntent = AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setEmailLink(link)
                .setAvailableProviders(providers)
                .build()
            signInLauncher.launch(signInIntent)
        }
    }

    Java

    if (AuthUI.canHandleIntent(getIntent())) {
        if (getIntent().getExtras() == null) {
            return;
        }
        String link = getIntent().getExtras().getString("email_link_sign_in");
        if (link != null) {
            Intent signInIntent = AuthUI.getInstance()
                    .createSignInIntentBuilder()
                    .setEmailLink(link)
                    .setAvailableProviders(providers)
                    .build();
            signInLauncher.launch(signInIntent);
        }
    }
  7. ไม่บังคับ รองรับการลงชื่อเข้าใช้ลิงก์อีเมลข้ามอุปกรณ์ ซึ่งหมายความว่าลิงก์ที่ส่งผ่านแอป Android จะใช้ลงชื่อเข้าสู่ระบบบนเว็บหรือแอปของ Apple ได้ โดยค่าเริ่มต้น ระบบจะเปิดใช้การสนับสนุนข้ามอุปกรณ์ คุณปิดใช้ได้โดยการเรียกใช้ setForceSameDevice บนอินสแตนซ์ EmailBuilder

    ดูข้อมูลเพิ่มเติมได้ที่ FirebaseUI-Web และ FirebaseUI-iOS

ออกจากระบบ

FirebaseUI ให้วิธีที่สะดวกในการออกจากระบบการตรวจสอบสิทธิ์ Firebase และผู้ให้บริการข้อมูลประจําตัวโซเชียลทั้งหมด

Kotlin+KTX

AuthUI.getInstance()
    .signOut(this)
    .addOnCompleteListener {
        // ...
    }

Java

AuthUI.getInstance()
        .signOut(this)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            public void onComplete(@NonNull Task<Void> task) {
                // ...
            }
        });

นอกจากนี้ คุณยังสามารถลบบัญชีของผู้ใช้ได้โดยสมบูรณ์ โดยทำดังนี้

Kotlin+KTX

AuthUI.getInstance()
    .delete(this)
    .addOnCompleteListener {
        // ...
    }

Java

AuthUI.getInstance()
        .delete(this)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // ...
            }
        });

การปรับแต่ง

โดยค่าเริ่มต้น FirebaseUI จะใช้ AppCompat สำหรับการกำหนดธีม ซึ่งหมายความว่าจะมีการใช้รูปแบบสีของแอปโดยค่าเริ่มต้น หากต้องการการปรับแต่งเพิ่มเติม คุณสามารถส่งธีมและโลโก้ไปยังเครื่องมือสร้าง Intent สำหรับการลงชื่อเข้าใช้ได้

Kotlin+KTX

val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .setLogo(R.drawable.my_great_logo) // Set logo drawable
    .setTheme(R.style.MySuperAppTheme) // Set theme
    .build()
signInLauncher.launch(signInIntent)

Java

Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .setLogo(R.drawable.my_great_logo)      // Set logo drawable
        .setTheme(R.style.MySuperAppTheme)      // Set theme
        .build();
signInLauncher.launch(signInIntent);

คุณยังสามารถตั้งนโยบายความเป็นส่วนตัวและข้อกำหนดในการให้บริการที่กำหนดเองได้ดังนี้

Kotlin+KTX

val signInIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .setTosAndPrivacyPolicyUrls(
        "https://example.com/terms.html",
        "https://example.com/privacy.html",
    )
    .build()
signInLauncher.launch(signInIntent)

Java

Intent signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .setTosAndPrivacyPolicyUrls(
                "https://example.com/terms.html",
                "https://example.com/privacy.html")
        .build();
signInLauncher.launch(signInIntent);

ขั้นตอนถัดไป