אימות עם Firebase ב-Android באמצעות מספר טלפון

אפשר להשתמש ב-Firebase Authentication כדי להכניס משתמש לחשבון באמצעות שליחת הודעת SMS לטלפון של המשתמש. המשתמש נכנס לחשבון באמצעות קוד חד-פעמי שמופיע בהודעת ה-SMS.

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

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

  1. אם עדיין לא הוספתם את Firebase לפרויקט Android, אתם צריכים להוסיף אותו.
  2. בקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל <project>/<app-module>/build.gradle.kts או <project>/<app-module>/build.gradle), מוסיפים את התלות בספריית Firebase Authentication ל-Android. מומלץ להשתמש ב-Firebase Android BoM כדי לשלוט בניהול גרסאות של הספרייה.
    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:35.1.0"))
    
        // 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:25.0.0")
    }
  3. אם עדיין לא קישרתם את האפליקציה לפרויקט ב-Firebase, אתם צריכים לעשות את זה דרך מסוף Firebase.
  4. אם עדיין לא הגדרתם את גיבוב ה-SHA-1 של האפליקציה במסוף Firebase, עשו זאת. ב אימות הלקוח מוסבר איך למצוא את גיבוב ה-SHA-1 של האפליקציה.

בעיות אבטחה

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

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

הפעלת כניסה באמצעות מספר טלפון בפרויקט ב-Firebase

כדי לאפשר למשתמשים להיכנס באמצעות SMS, קודם צריך להפעיל את שיטת הכניסה באמצעות מספר טלפון בפרויקט Firebase:

  1. במסוף Firebase, נכנסים אל אבטחה > אימות.
  2. בכרטיסייה שיטת התחברות, מפעילים את ספק הכניסה Phone.
  3. מגדירים מדיניות באזורים שבהם רוצים לאפשר או לאסור שליחת הודעות SMS. הגדרת מדיניות אזורית ל-SMS יכולה לעזור להגן על האפליקציות מפני ניצול לרעה של SMS. בפרויקטים חדשים, מדיניות ברירת המחדל לא מאפשרת אזורים.
    1. במסוף Firebase, נכנסים לכרטיסייה Security ‏> Authentication ‏> Settings.
    2. בקטע מדיניות אזורית בנושא SMS, מגדירים את המדיניות האזורית בנושא SMS.

הפעלת אימות אפליקציות

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

  • ‫Play Integrity API: אם במכשיר של המשתמש מותקנת האפליקציה Google Play services, והאפליקציה Firebase Authentication יכולה לאמת את המכשיר כלגיטימי באמצעות Play Integrity API, אפשר להמשיך בתהליך הכניסה באמצעות מספר הטלפון. ‫Play Integrity API מופעל בפרויקט בבעלות Google על ידי Firebase Authentication, ולא בפרויקט שלך. הפעולה הזו לא משפיעה על המכסות של Play Integrity API בפרויקט. התמיכה ב-Play Integrity זמינה ב-Authentication SDK בגרסה 21.2.0 ואילך (Firebase BoM בגרסה 31.4.0 ואילך).

    כדי להשתמש ב-Play Integrity, צריך לציין את טביעת האצבע בפורמט SHA-256 של האפליקציה, אם עדיין לא עשיתם את זה.

    1. במסוף Firebase, נכנסים לכרטיסייה הגדרות > כללי.
    2. גוללים למטה לכרטיס Your apps, בוחרים את האפליקציה ל-Android ומוסיפים את טביעת האצבע מסוג SHA-256 בשדה SHA certificate fingerprints.

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

  • אימות מסוג reCAPTCHA: אם אי אפשר להשתמש ב-Play Integrity, למשל אם למשתמש יש מכשיר שלא מותקן בו Google Play services, Firebase Authentication משתמש באימות מסוג reCAPTCHA כדי להשלים את תהליך הכניסה באמצעות הטלפון. במקרים רבים, המשתמשים יכולים להשלים את מבחן reCAPTCHA בלי לפתור שום דבר. חשוב לזכור: כדי להשתמש בתהליך הזה, צריך לשייך SHA-1 לאפליקציה. בתהליך הזה, צריך גם שמפתח ה-API לא יהיה מוגבל או שיהיה ברשימת ההיתרים של PROJECT_ID.firebaseapp.com.

    הנה כמה תרחישים שבהם reCAPTCHA מופעל:

    • אם במכשיר של משתמש הקצה לא מותקנת האפליקציה Google Play services.
    • אם האפליקציה לא מופצת דרך Google Play Store (ב-Authentication SDK בגרסה 21.2.0 ואילך).
    • אם אסימון SafetyNet שהתקבל לא היה חוקי (בגרסאות SDK של Authentication < v21.2.0).

    כשמשתמשים ב-SafetyNet או ב-Play Integrity לאימות אפליקציות, השדה %APP_NAME% בתבנית ה-SMS מאוכלס בשם האפליקציה שנקבע על ידי Google Play Store. בתרחישים שבהם מופעל reCAPTCHA, הערך של %APP_NAME% מאוכלס בתור PROJECT_ID.firebaseapp.com.

אפשר לאלץ את תהליך האימות מסוג reCAPTCHA באמצעות forceRecaptchaFlowForTesting אפשר להשבית את אימות האפליקציות (כשמשתמשים במספרי טלפון פיקטיביים) באמצעות setAppVerificationDisabledForTesting.

פתרון בעיות

  • השגיאה "Missing initial state" כשמשתמשים ב-reCAPTCHA לאימות אפליקציות

    זה יכול לקרות כשתהליך ה-reCAPTCHA מסתיים בהצלחה אבל לא מפנה את המשתמש בחזרה לאפליקציית הנייטיב. במקרים כאלה, המשתמש מופנה לכתובת ה-URL לגיבוי PROJECT_ID.firebaseapp.com/__/auth/handler. בדפדפני Firefox, האפשרות לפתוח קישורים לאפליקציות נייטיב מושבתת כברירת מחדל. אם השגיאה שלמעלה מופיעה ב-Firefox, פועלים לפי השלבים במאמר הגדרת Firefox ל-Android לפתיחת קישורים באפליקציות נייטיב כדי להפעיל פתיחה של קישורים לאפליקציות.

שליחת קוד אימות לטלפון של המשתמש

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

לאחר מכן, מעבירים את מספר הטלפון שלהם ל-method‏ PhoneAuthProvider.verifyPhoneNumber כדי לבקש מ-Firebase לאמת את מספר הטלפון של המשתמש. לדוגמה:

Kotlin

val options = PhoneAuthOptions.newBuilder(auth)
    .setPhoneNumber(phoneNumber) // Phone number to verify
    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
    .setActivity(this) // Activity (for callback binding)
    .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Java

PhoneAuthOptions options = 
  PhoneAuthOptions.newBuilder(mAuth) 
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // (optional) Activity for callback binding
      // If no activity is passed, reCAPTCHA verification can not be used.
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);     

ה-method‏ verifyPhoneNumber היא reentrant: אם קוראים לה כמה פעמים, למשל ב-method‏ onStart של פעילות, ה-method‏ verifyPhoneNumber לא תשלח הודעת SMS שנייה, אלא אם הזמן הקצוב לתפוגה של הבקשה המקורית חלף.

אתם יכולים להשתמש בהתנהגות הזו כדי להמשיך את תהליך הכניסה באמצעות מספר הטלפון אם האפליקציה נסגרת לפני שהמשתמש יכול להיכנס (לדוגמה, כשהמשתמש משתמש באפליקציית סמס שלו). אחרי שקוראים ל-verifyPhoneNumber, מגדירים דגל שמציין שהאימות בתהליך. לאחר מכן, שומרים את הדגל ב-method‏ onSaveInstanceState של הפעילות ומשחזרים את הדגל ב-onRestoreInstanceState. לבסוף, בשיטה onStart של הפעילות, בודקים אם האימות כבר מתבצע, ואם כן, קוראים שוב ל-verifyPhoneNumber. חשוב לנקות את הדגל כשהאימות מסתיים או נכשל (ראו קריאות חוזרות (callbacks) לאימות).

כדי לטפל בקלות בסיבוב המסך ובמקרים אחרים של הפעלה מחדש של Activity, מעבירים את ה-Activity ל-method‏ verifyPhoneNumber. הקריאות החוזרות ינותקו אוטומטית כשה-Activity תיפסק, כך שתוכלו לכתוב קוד מעבר של ממשק המשתמש בשיטות הקריאה החוזרת.

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

Kotlin

auth.setLanguageCode("fr")
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage()

Java

auth.setLanguageCode("fr");
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage();

כשקוראים ל-PhoneAuthProvider.verifyPhoneNumber, צריך גם לספק מופע של OnVerificationStateChangedCallbacks, שמכיל הטמעות של פונקציות הקריאה החוזרת שמטפלות בתוצאות של הבקשה. לדוגמה:

Kotlin

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    override fun onVerificationCompleted(credential: PhoneAuthCredential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:$credential")
        signInWithPhoneAuthCredential(credential)
    }

    override fun onVerificationFailed(e: FirebaseException) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e)

        if (e is FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e is FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    override fun onCodeSent(
        verificationId: String,
        token: PhoneAuthProvider.ForceResendingToken,
    ) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:$verificationId")

        // Save verification ID and resending token so we can use them later
        storedVerificationId = verificationId
        resendToken = token
    }
}

Java

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

קריאות חוזרות (callbacks) לאימות

ברוב האפליקציות, מטמיעים את פונקציות ה-callback‏ onVerificationCompleted, onVerificationFailed ו-onCodeSent. יכול להיות שתצטרכו להטמיע גם את onCodeAutoRetrievalTimeOut, בהתאם לדרישות של האפליקציה.

onVerificationCompleted(PhoneAuthCredential)‎

השיטה הזו נקראת בשני מצבים:

  • אימות מיידי: במקרים מסוימים אפשר לאמת את מספר הטלפון באופן מיידי בלי לשלוח או להזין קוד אימות.
  • אחזור אוטומטי: במכשירים מסוימים, Google Play Services יכולים לזהות באופן אוטומטי את הודעת ה-SMS לאימות שנכנסת ולבצע אימות בלי פעולה מצד המשתמש. (יכול להיות שהאפשרות הזו לא תהיה זמינה אצל חלק מהספקים). האימות הזה מתבצע באמצעות SMS Retriever API, שכולל ערך גיבוב (hash) באורך 11 תווים בסוף הודעת ה-SMS.
בכל מקרה, מספר הטלפון של המשתמש אומת בהצלחה, ואפשר להשתמש באובייקט PhoneAuthCredential שמועבר לקריאה החוזרת (callback) כדי להכניס את המשתמש לחשבון.

onVerificationFailed(FirebaseException)

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

onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken)‎

זה שינוי אופציונלי. השיטה הזו נקראת אחרי שקוד האימות נשלח ב-SMS למספר הטלפון שצוין.

כשמתבצעת קריאה לשיטה הזו, רוב האפליקציות מציגות ממשק משתמש שמבקש מהמשתמש להקליד את קוד האימות מהודעת ה-SMS. (במקביל, יכול להיות שהאימות האוטומטי ימשיך ברקע). לאחר מכן, אחרי שהמשתמש מקליד את קוד האימות, אתם יכולים להשתמש בקוד האימות ובמזהה האימות שהועבר ל-method כדי ליצור אובייקט PhoneAuthCredential, שבו תוכלו להשתמש כדי להכניס את המשתמש לחשבון. עם זאת, יכול להיות שבאפליקציות מסוימות ממשק המשתמש של קוד האימות יוצג רק אחרי הקריאה ל-onCodeAutoRetrievalTimeOut (לא מומלץ).

onCodeAutoRetrievalTimeOut(String verificationId)

זה שינוי אופציונלי. המערכת קוראת ל-method הזו אחרי שמשך הזמן הקצוב לתפוגה שצוין ב-verifyPhoneNumber חלף בלי ש-onVerificationCompleted הופעל קודם. במכשירים ללא כרטיסי SIM, השיטה הזו נקראת באופן מיידי כי לא ניתן לאחזר הודעות SMS באופן אוטומטי.

באפליקציות מסוימות, המשתמשים לא יכולים להזין קוד עד שתקופת האימות האוטומטי מסתיימת, ורק אז מוצג ממשק משתמש שמבקש מהמשתמשים להקליד את קוד האימות מהודעת ה-SMS (לא מומלץ).

יצירת אובייקט PhoneAuthCredential

אחרי שהמשתמש מזין את קוד האימות ש-Firebase שלחה לטלפון שלו, יוצרים אובייקט PhoneAuthCredential באמצעות קוד האימות ומזהה האימות שהועבר לקריאה החוזרת (callback) של onCodeSent או onCodeAutoRetrievalTimeOut. (כשמפעילים את onVerificationCompleted, מקבלים אובייקט PhoneAuthCredential ישירות, כך שאפשר לדלג על השלב הזה).

כדי ליצור את האובייקט PhoneAuthCredential, מפעילים את PhoneAuthProvider.getCredential:

Kotlin

val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

Java

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

המשתמש נכנס לחשבון

אחרי שמקבלים אובייקט PhoneAuthCredential, באמצעות פונקציית ה-callback‏ onVerificationCompleted או באמצעות קריאה ל-PhoneAuthProvider.getCredential, משלימים את תהליך הכניסה על ידי העברת האובייקט PhoneAuthCredential אל FirebaseAuth.signInWithCredential:

Kotlin

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    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 = task.result?.user
            } else {
                // Sign in failed, display a message and update the UI
                Log.w(TAG, "signInWithCredential:failure", task.exception)
                if (task.exception is FirebaseAuthInvalidCredentialsException) {
                    // The verification code entered was invalid
                }
                // Update UI
            }
        }
}

Java

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    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 = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

בדיקה עם מספרי טלפון פיקטיביים

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

  • בודקים את האימות של מספר הטלפון בלי לנצל את מכסת השימוש.
  • בודקים את האימות של מספר הטלפון בלי לשלוח הודעת SMS בפועל.
  • להריץ בדיקות ברצף עם אותו מספר טלפון בלי שהמערכת תגביל אתכם. כך אפשר לצמצם את הסיכון לדחייה במהלך תהליך הבדיקה של חנות האפליקציות, אם הבודק משתמש באותו מספר טלפון לבדיקה.
  • אפשר לבצע בדיקות בקלות בסביבות פיתוח בלי מאמץ נוסף, למשל לפתח בסימולטור של iOS או באמולטור Android בלי Google Play Services.
  • לכתוב בדיקות שילוב בלי להיחסם על ידי בדיקות אבטחה שבדרך כלל מופעלות על מספרי טלפון אמיתיים בסביבת ייצור.

מספרי טלפון פיקטיביים צריכים לעמוד בדרישות הבאות:

  1. חשוב להשתמש במספרי טלפון שהם באמת פיקטיביים ולא קיימים כבר. ב-Firebase Authentication אי אפשר להגדיר מספרי טלפון קיימים של משתמשים אמיתיים כמספרי בדיקה. אפשרות אחת היא להשתמש במספרים עם הקידומת 555 כמספרי טלפון לבדיקה בארה"ב, לדוגמה: ‎+1 650-555-3434
  2. מספרי הטלפון צריכים להיות בפורמט הנכון מבחינת האורך ומגבלות אחרות. הם עדיין יעברו את אותו תהליך אימות כמו מספר טלפון של משתמש אמיתי.
  3. אפשר להוסיף עד 10 מספרי טלפון לפיתוח.
  4. השתמשו במספרי טלפון או בקודים לבדיקה שקשה לנחש, והחליפו אותם לעיתים קרובות.

יצירת מספרי טלפון וקודי אימות פיקטיביים

  1. במסוף Firebase, נכנסים אל אבטחה > אימות.
  2. בכרטיסייה שיטת התחברות, מפעילים את ספק הכניסה Phone, אם הוא עדיין לא מופעל.
  3. מרחיבים את הקטע מספרי טלפון לבדיקה.
  4. מזינים את מספר הטלפון שרוצים לבדוק, לדוגמה: +1 650-555-3434.
  5. מזינים את קוד האימות בן 6 הספרות של המספר הספציפי הזה, לדוגמה: 654321.
  6. לוחצים על הוספה לכל מספר. אם צריך, אפשר למחוק את מספר הטלפון והקוד שלו. כדי לעשות את זה, מעבירים את העכבר מעל השורה המתאימה ולוחצים על סמל פח האשפה.

בדיקה ידנית

אתם יכולים להתחיל להשתמש במספר טלפון פיקטיבי ישירות באפליקציה. כך תוכלו לבצע בדיקות ידניות בשלבי הפיתוח בלי להיתקל בבעיות של מכסות או הגבלת קצב. אפשר גם לבדוק ישירות מסימולטור של iOS או מאמולטור Android בלי להתקין את Google Play Services.

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

בסיום הכניסה, נוצר משתמש Firebase עם מספר הטלפון הזה. המשתמש מתנהג כמו משתמש עם מספר טלפון אמיתי ויש לו את אותם מאפיינים, והוא יכול לגשת אל Realtime Database/Cloud Firestore ולשירותים אחרים באותו אופן. לטוקן של המזהה שנוצר בתהליך הזה יש את אותה חתימה כמו למשתמש אמיתי עם מספר טלפון.

אפשרות נוספת היא להגדיר תפקיד בדיקה באמצעות הצהרות מותאמות אישית למשתמשים האלה כדי להבדיל אותם כמשתמשים מזויפים, אם רוצים להגביל עוד יותר את הגישה.

כדי להפעיל ידנית את תהליך ה-reCAPTCHA לבדיקה, משתמשים ב-method‏ forceRecaptchaFlowForTesting().

// Force reCAPTCHA flow
FirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();

בדיקת אינטגרציה

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

ב-Android, צריך להפעיל את setAppVerificationDisabledForTesting() לפני הקריאה ל-signInWithPhoneNumber. הפעולה הזו משביתה את אימות האפליקציה באופן אוטומטי, ומאפשרת לכם להעביר את מספר הטלפון בלי לפתור את האימות באופן ידני. גם אם Play Integrity ו-reCAPTCHA מושבתים, לא תוכלו להשלים את הכניסה באמצעות מספר טלפון אמיתי. אפשר להשתמש ב-API הזה רק עם מספרי טלפון פיקטיביים.

// Turn off phone auth app verification.
FirebaseAuth.getInstance().getFirebaseAuthSettings()
   .setAppVerificationDisabledForTesting();

התקשרות אל verifyPhoneNumber עם מספר פיקטיבי מפעילה את פונקציית ה-callback‏ onCodeSent, שבה צריך לספק את קוד האימות המתאים. כך אפשר לבצע בדיקות באמולטורים של Android.

Java

String phoneNum = "+16505554567";
String testVerificationCode = "123456";

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
FirebaseAuth auth = FirebaseAuth.getInstance();
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                MainActivity.this.enableUserManuallyInputCode();
            }

            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            @Override
            public void onVerificationFailed(@NonNull FirebaseException e) {
                // ...
            }
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

val phoneNum = "+16505554567"
val testVerificationCode = "123456"

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
val options = PhoneAuthOptions.newBuilder(Firebase.auth)
    .setPhoneNumber(phoneNum)
    .setTimeout(30L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        override fun onCodeSent(
            verificationId: String,
            forceResendingToken: PhoneAuthProvider.ForceResendingToken,
        ) {
            // Save the verification id somewhere
            // ...

            // The corresponding whitelisted code above should be used to complete sign-in.
            this@MainActivity.enableUserManuallyInputCode()
        }

        override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
            // Sign in with the credential
            // ...
        }

        override fun onVerificationFailed(e: FirebaseException) {
            // ...
        }
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

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

כשקוראים ל-verifyPhoneNumber, הוא מפעיל את onVerificationCompleted עם PhoneAuthCredential באופן ישיר. האפשרות הזו פועלת רק עם מספרי טלפון פיקטיביים.

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

Java

// The test phone number and code should be whitelisted in the console.
String phoneNumber = "+16505554567";
String smsCode = "123456";

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings();

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode);

PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

// The test phone number and code should be whitelisted in the console.
val phoneNumber = "+16505554567"
val smsCode = "123456"

val firebaseAuth = Firebase.auth
val firebaseAuthSettings = firebaseAuth.firebaseAuthSettings

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode)

val options = PhoneAuthOptions.newBuilder(firebaseAuth)
    .setPhoneNumber(phoneNumber)
    .setTimeout(60L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        override fun onVerificationCompleted(credential: PhoneAuthCredential) {
            // Instant verification is applied and a credential is directly returned.
            // ...
        }

        // ...
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

השלבים הבאים

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

  • באפליקציות, אתם יכולים לקבל את פרטי הפרופיל הבסיסיים של המשתמש מהאובייקט FirebaseUser. ניהול משתמשים

  • בכללי האבטחה של Firebase Realtime Database ו-Cloud Storage, אפשר לקבל את מזהה המשתמש הייחודי של המשתמש המחובר מהמשתנה auth, ולהשתמש בו כדי לקבוע לאילו נתונים המשתמש יכול לגשת.

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

כדי להוציא משתמש מהחשבון, מפעילים את signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();