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

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

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

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

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

  2. מוסיפים את יחסי התלות של 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'
    }
    

    ל-FirebaseUI Auth SDK יש יחסי תלות טרנזיטיביים ב-Firebase SDK וב-Google Play Services SDK.

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

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

    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 שמירשם קריאה חוזרת (callback) עבור חוזה התוצאה של הפעילות ב-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, פותחים את הקטע Authentication. בכרטיסייה Sign in method מפעילים את הספק Email/Password. חשוב לזכור: כדי להשתמש בכניסה באמצעות קישור לאימייל, צריך להפעיל את הכניסה באמצעות כתובת אימייל/סיסמה.

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

  3. תצטרכו גם להפעיל קישורים דינמיים ב-Firebase כדי להשתמש בכניסה באמצעות קישור לאימייל. במסוף Firebase, לוחצים על קישורים דינמיים בקטע מעורבות בסרגל הניווט. לוחצים על תחילת העבודה ומוסיפים דומיין. הדומיין שתבחרו כאן יופיע בקישורים באימייל שיישלחו למשתמשים.

  4. כדי להפעיל את הכניסה באמצעות קישור לאימייל ב-FirebaseUI, צריך להפעיל את enableEmailLinkSignIn במכונה של EmailBuilder. בנוסף, תצטרכו לספק אובייקט ActionCodeSettings תקין עם הערך setHandleCodeInApp מוגדר כ-true. בנוסף, צריך להוסיף לרשימת ההיתרים את כתובת ה-URL שמעבירים אל setUrl. אפשר לעשות זאת במסוף Firebase, בקטע Authentication (אימות) -> Sign in Methods (שיטות כניסה) -> Authorized domains (דומיינים מורשים).

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

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

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 ואתם רוצים לדווח עליה, תוכלו להשתמש בכלי למעקב אחר בעיות ב-GitHub.