מוסיפים בקלות כניסה לאפליקציה ל-Android באמצעות FirebaseUI

FirebaseUI היא ספרייה שמבוססת על אימות ב-Firebase SDK ומספקת תהליכי ממשק משתמש מוכנים לשימוש באפליקציה. היתרונות של FirebaseUI:

  • כמה ספקים – תהליכי כניסה לאימייל/סיסמה, לקישור באימייל, לאימות טלפוני, לכניסה באמצעות חשבון Google, לכניסה באמצעות פייסבוק, לכניסה באמצעות טוויטר ולכניסה באמצעות GitHub.
  • ניהול חשבונות – תהליכים לטיפול במשימות של ניהול חשבונות, כמו יצירת חשבון ואיפוס סיסמאות.
  • קישור חשבונות – תהליכים לקישור בטוח של חשבונות משתמשים בין ספקי זהויות.
  • שדרוג של משתמשים אנונימיים – תהליכים לשדרוג בטוח של משתמשים אנונימיים.
  • ערכות נושא בהתאמה אישית – אפשר להתאים אישית את המראה של FirebaseUI כך שיתאים לאפליקציה. בנוסף, מכיוון ש-FirebaseUI הוא קוד פתוח, אפשר ליצור העתק של הפרויקט ולבצע התאמה אישית בדיוק לפי הצרכים שלכם.
  • Credential Manager – שילוב אוטומטי עם Credential Manager לכניסה מהירה בין מכשירים.

לפני שמתחילים

  1. אם עדיין לא עשיתם זאת, אתם צריכים להוסיף את Firebase לפרויקט Android.

  2. מוסיפים את יחסי התלות של FirebaseUI לקובץ build.gradle(.kts) ברמת האפליקציה. אם רוצים לתמוך בכניסה באמצעות Facebook או Twitter, צריך לכלול גם את ערכות ה-SDK של Facebook ו-Twitter:

        dependencies {
            // ...
    
            implementation("com.firebaseui:firebase-ui-auth:9.0.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")
        }
    

    ל-FirebaseUI Auth SDK יש תלות טרנזיטיבית ב-Firebase SDK וב-Google Play services SDK.

  3. במסוף Firebase, עוברים אל Security (אבטחה) >‏ Authentication (אימות).

  4. בכרטיסייה שיטת הכניסה, מפעילים את ספקי הכניסה שרוצים לתמוך בהם. חלק מספקי הכניסה דורשים מידע נוסף, שבדרך כלל זמין במסוף המפתחים של השירות.

  5. אם הפעלתם את הכניסה באמצעות חשבון Google:

    1. מעדכנים את קובץ ההגדרות של Firebase.

      1. כשמוצגת בקשה במסוף Firebase, מורידים את קובץ ההגדרות המעודכן של Firebase ‏ (google-services.json), שכולל עכשיו את פרטי לקוח ה-OAuth שנדרשים לכניסה באמצעות חשבון Google.

      2. מעבירים את קובץ התצורה המעודכן הזה לפרויקט ב-Android Studio, ומחליפים את קובץ התצורה התואם שכבר לא עדכני. (ראו איך מוסיפים את Firebase לפרויקט Android).

    2. אם עדיין לא עשיתם זאת, מציינים את טביעת האצבע מסוג SHA-1 של האפליקציה.

      1. במסוף Firebase, עוברים אל הגדרות > הכרטיסייה כללי.

      2. גוללים למטה אל הכרטיס האפליקציות שלך, בוחרים את האפליקציה ל-Android ומוסיפים את טביעת האצבע מסוג SHA-1 בשדה טביעות אצבע לאישור SHA.

      במאמר אימות הלקוח מוסבר איך מקבלים את טביעת האצבע של ה-SHA של האפליקציה.

  6. אם אתם תומכים בכניסה באמצעות פייסבוק או טוויטר, אתם צריכים להוסיף משאבי מחרוזות ל-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

// 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, יוצרים כוונת כניסה עם שיטות הכניסה המועדפות:

Kotlin

// 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

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, עוברים אל Security (אבטחה) >‏ Authentication (אימות).

  2. בכרטיסייה שיטת כניסה, מפעילים את שיטת הכניסה אימייל/סיסמה. שימו לב: כדי להשתמש בכניסה באמצעות קישור באימייל, צריך להפעיל את הכניסה באמצעות אימייל או סיסמה.

  3. באותו קטע, מפעילים את שיטת הכניסה Email link (passwordless sign-in) (קישור באימייל (כניסה ללא סיסמה)) ולוחצים על Save (שמירה).

  4. כדי להשתמש בכניסה באמצעות קישור באימייל, צריך גם להפעיל את Firebase Dynamic Links:

    1. במסוף Firebase, עוברים אל DevOps & Engagement (פיתוח אפליקציות ואינטראקציה) > Dynamic Links (קישורים דינמיים).

    2. לוחצים על תחילת העבודה ואז מוסיפים דומיין. הדומיין שתבחרו כאן יופיע בקישורים לאימייל שיישלחו למשתמשים.

  5. כדי להפעיל כניסה באמצעות קישור באימייל ב-FirebaseUI, צריך להתקשר אל enableEmailLinkSignIn במופע EmailBuilder. תצטרכו גם לספק אובייקט תקין מסוג ActionCodeSettings עם הערך true במאפיין setHandleCodeInApp.

    בנוסף, צריך להוסיף לרשימת ההיתרים את כתובת ה-URL שמעבירים אל setUrl:

    1. במסוף Firebase, עוברים אל Security (אבטחה) > Authentication (אימות) > הכרטיסייה Settings (הגדרות).

    2. בקטע דומיינים מורשים, לוחצים על הוספת דומיין ומוסיפים את הדומיין.

    Kotlin

    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);
  6. אם רוצים לראות את הקישור בפעילות ספציפית, אפשר לפעול לפי השלבים שמפורטים כאן. אחרת, הקישור יפנה מחדש לפעילות במרכז האפליקציות.

  7. אחרי שתזהו את קישור העומק, תצטרכו להתקשר כדי לוודא שנוכל לטפל בו בשבילכם. אם נוכל, תצטרכו להעביר לנו את המסמך באמצעות setEmailLink.

    Kotlin

    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);
        }
    }
  8. אופציונלי יש תמיכה בכניסה באמצעות קישור באימייל במכשירים שונים, כלומר אפשר להשתמש בקישור שנשלח דרך אפליקציית Android כדי להיכנס לאפליקציות באינטרנט או לאפליקציות של Apple. כברירת מחדל, התמיכה במכשירים מקושרים מופעלת. כדי להשבית את התכונה, מתקשרים אל setForceSameDevice במופע EmailBuilder.

    מידע נוסף זמין במאמרים בנושא FirebaseUI-Web ו-FirebaseUI-iOS.

יציאה

ספריית FirebaseUI מספקת שיטות נוחות להתנתקות מאימות ב-Firebase ומכל ספקי הזהויות ברשתות החברתיות:

Kotlin

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

Java

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

אפשר גם למחוק לגמרי את חשבון המשתמש:

Kotlin

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

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

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);

השלבים הבאים

  • מידע נוסף על שימוש ב-FirebaseUI ועל התאמה אישית שלו זמין בקובץ README ב-GitHub.
  • אם נתקלתם בבעיה ב-FirebaseUI ואתם רוצים לדווח עליה, אתם יכולים להשתמש בכלי Issue Tracker ב-GitHub.