المصادقة من خلال Firebase على Android باستخدام رقم هاتف

يمكنك استخدام Firebase Authentication لتسجيل دخول مستخدم من خلال إرسال رسالة SMS إلى هاتفه. يسجّل المستخدم الدخول باستخدام رمز يُستخدَم لمرة واحدة وارد في رسالة SMS.

أسهل طريقة لإضافة ميزة تسجيل الدخول باستخدام رقم الهاتف إلى تطبيقك هي استخدام FirebaseUI، التي تتضمّن أداة تسجيل دخول جاهزة للاستخدام تنفّذ عمليات تسجيل الدخول باستخدام رقم الهاتف، بالإضافة إلى تسجيل الدخول المستند إلى كلمة المرور وتسجيل الدخول الموحّد. يوضّح هذا المستند كيفية تنفيذ عملية تسجيل الدخول باستخدام رقم الهاتف من خلال حزمة تطوير البرامج (SDK) لمنصة Firebase.

قبل البدء

  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:34.0.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متعدّدة في تطبيقك، ننصحك بشدة باستخدام 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:24.0.0")
    }
  3. إذا لم يسبق لك ربط تطبيقك بمشروعك على Firebase، يمكنك إجراء ذلك من Firebase وحدة التحكّم.
  4. إذا لم يسبق لك ضبط تجزئة SHA-1 لتطبيقك في وحدة تحكّم Firebase، عليك إجراء ذلك. راجِع مصادقة العميل للحصول على معلومات حول العثور على تجزئة SHA-1 لتطبيقك.

المخاوف المرتبطة بالأمان

على الرغم من أنّ المصادقة باستخدام رقم الهاتف فقط هي طريقة سهلة، إلا أنّها أقل أمانًا من الطرق الأخرى المتاحة، لأنّه يمكن نقل ملكية رقم الهاتف بسهولة بين المستخدمين. بالإضافة إلى ذلك، على الأجهزة التي تتضمّن ملفات شخصية متعددة للمستخدمين، يمكن لأي مستخدم يمكنه تلقّي رسائل SMS تسجيل الدخول إلى حساب باستخدام رقم هاتف الجهاز.

إذا كنت تستخدم ميزة تسجيل الدخول المستندة إلى رقم الهاتف في تطبيقك، عليك توفيرها إلى جانب طرق تسجيل دخول أكثر أمانًا، وإبلاغ المستخدمين بمزايا وعيوب الأمان عند استخدام ميزة تسجيل الدخول المستندة إلى رقم الهاتف.

تفعيل ميزة "تسجيل الدخول باستخدام رقم الهاتف" لمشروعك على Firebase

لتسجيل دخول المستخدمين باستخدام الرسائل القصيرة، يجب أولاً تفعيل طريقة تسجيل الدخول باستخدام رقم الهاتف لمشروعك على Firebase باتّباع الخطوات التالية:

  1. في وحدة تحكّم Firebase، افتح قسم المصادقة.
  2. في صفحة طريقة تسجيل الدخول، فعِّل طريقة تسجيل الدخول باستخدام رقم الهاتف.

تفعيل ميزة "التحقّق من التطبيق"

لاستخدام ميزة المصادقة باستخدام رقم الهاتف، يجب أن يتمكّن 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 الإصدار 21.2.0 أو إصدار أحدث من حزمة تطوير البرامج (SDK) (Firebase BoM الإصدار 31.4.0 أو إصدار أحدث).

    لاستخدام Play Integrity، إذا لم يسبق لك تحديد الملف المرجعي SHA-256 لتطبيقك، عليك إجراء ذلك من إعدادات المشروع في وحدة تحكّم Firebase. راجِع مقالة مصادقة العميل للحصول على تفاصيل حول كيفية الحصول على بصمة الإصبع SHA-256 لتطبيقك.

  • التحقّق من reCAPTCHA: في حال تعذُّر استخدام Play Integrity، مثلما يحدث عندما يكون لدى المستخدم جهاز بدون Google Play services مثبَّت، Firebase Authentication يتم استخدام عملية التحقّق من reCAPTCHA لإكمال عملية تسجيل الدخول باستخدام الهاتف. يمكن في كثير من الأحيان إكمال تحدّي reCAPTCHA بدون أن يضطر المستخدم إلى حلّ أي شيء. يُرجى العِلم أنّ هذا الإجراء يتطلّب ربط رمز SHA-1 بتطبيقك. يتطلّب هذا المسار أيضًا أن يكون مفتاح واجهة برمجة التطبيقات غير مقيّد أو مدرَجًا في القائمة المسموح بها لـ PROJECT_ID.firebaseapp.com.

    بعض السيناريوهات التي يتم فيها تفعيل reCAPTCHA:

    عند استخدام SafetyNet أو Play Integrity للتحقّق من التطبيق، تتم تعبئة الحقل %APP_NAME% في نموذج الرسالة القصيرة باسم التطبيق الذي يتم تحديده من Google Play Store. في الحالات التي يتم فيها تفعيل reCAPTCHA، يتم ملء %APP_NAME% بالقيمة PROJECT_ID.firebaseapp.com.

يمكنك فرض خطوات التحقّق من reCAPTCHA باستخدام forceRecaptchaFlowForTesting يمكنك إيقاف ميزة "التحقّق من التطبيق" (عند استخدام أرقام هواتف وهمية) باستخدام setAppVerificationDisabledForTesting.

تحديد المشاكل وحلّها

  • رسالة الخطأ "الحالة الأولية غير متوفّرة" عند استخدام reCAPTCHA للتحقّق من التطبيق

    يمكن أن يحدث ذلك عند اكتمال عملية reCAPTCHA بنجاح ولكن بدون إعادة توجيه المستخدم إلى التطبيق الأصلي. في حال حدوث ذلك، ستتم إعادة توجيه المستخدم إلى عنوان URL الاحتياطي PROJECT_ID.firebaseapp.com/__/auth/handler. في متصفّحات Firefox، يكون خيار فتح روابط التطبيقات الأصلية غير مفعّل تلقائيًا. إذا ظهرت لك رسالة الخطأ أعلاه على Firefox، اتّبِع الخطوات الواردة في ضبط Firefox على Android لفتح الروابط في التطبيقات الأصلية لتفعيل فتح روابط التطبيقات.

إرسال رمز تأكيد إلى هاتف المستخدم

لبدء عملية تسجيل الدخول باستخدام رقم الهاتف، اعرض على المستخدم واجهة تطلب منه كتابة رقم هاتفه. تختلف المتطلبات القانونية، ولكن كأفضل ممارسة ولتحديد توقعات المستخدمين، عليك إعلامهم بأنّه في حال استخدام ميزة "تسجيل الدخول باستخدام الهاتف"، قد يتلقّون رسالة SMS لإثبات الملكية وسيتم تطبيق الأسعار العادية.

بعد ذلك، مرِّر رقم الهاتف إلى الطريقة 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);     

الطريقة verifyPhoneNumber قابلة لإعادة الدخول: إذا استدعيتها عدة مرات، مثلاً في الطريقة onStart الخاصة بأحد الأنشطة، لن ترسل الطريقة verifyPhoneNumber رسالة SMS ثانية إلا إذا انتهت المهلة المحددة للطلب الأصلي.

يمكنك استخدام هذا السلوك لاستئناف عملية تسجيل الدخول باستخدام رقم الهاتف إذا تم إغلاق تطبيقك قبل أن يتمكّن المستخدم من تسجيل الدخول (على سبيل المثال، أثناء استخدام المستخدم لتطبيق الرسائل القصيرة). بعد الاتصال بالرقم verifyPhoneNumber، اضبط علامة تشير إلى أنّ عملية إثبات الهوية قيد التقدّم. بعد ذلك، احفظ العلامة في طريقة onSaveInstanceState الخاصة بنشاطك واستعِدها في onRestoreInstanceState. أخيرًا، في طريقة onStartActivityonStart، تحقَّق مما إذا كانت عملية إثبات الملكية قيد التقدّم، وإذا كان الأمر كذلك، اتّصِل بالرقم verifyPhoneNumber مرة أخرى. احرص على محو العلامة عند اكتمال عملية التحقّق أو تعذّرها (راجِع عمليات معاودة الاتصال المتعلقة بالتحقّق).

للتعامل بسهولة مع تدوير الشاشة وحالات أخرى لإعادة تشغيل النشاط، مرِّر النشاط إلى الطريقة verifyPhoneNumber. سيتم فصل عمليات الاسترجاع تلقائيًا عند توقّف النشاط، لذا يمكنك كتابة رمز انتقال واجهة المستخدم بحرية في طرق الاسترجاع.

يمكن أيضًا توفير نسخة مترجَمة من رسالة 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;
    }
};

عمليات رد الاتصال لإثبات الملكية

في معظم التطبيقات، عليك تنفيذ عمليات ردّ الاتصال onVerificationCompleted وonVerificationFailed وonCodeSent. يمكنك أيضًا تنفيذ onCodeAutoRetrievalTimeOut، حسب متطلبات تطبيقك.

onVerificationCompleted(PhoneAuthCredential)

يتم استدعاء هذه الطريقة في حالتين:

  • التأكيد الفوري: في بعض الحالات، يمكن تأكيد رقم الهاتف بشكل فوري بدون الحاجة إلى إرسال رمز تأكيد أو إدخاله.
  • الاسترداد التلقائي: على بعض الأجهزة، يمكن لخدمات Google Play رصد الرسالة القصيرة الواردة التي تتضمّن رمز التحقّق تلقائيًا وإجراء عملية التحقّق بدون أن يتّخذ المستخدم أي إجراء. (قد لا تتوفّر هذه الإمكانية مع بعض شركات النقل). يتم ذلك باستخدام SMS Retriever API، الذي يتضمّن رمزًا مجزأً مكوّنًا من 11 حرفًا في نهاية رسالة SMS.
في كلتا الحالتين، تم إثبات ملكية رقم هاتف المستخدم بنجاح، ويمكنك استخدام العنصر PhoneAuthCredential الذي تم تمريره إلى الدالة الاحتياطية من أجل تسجيل دخول المستخدم.

onVerificationFailed(FirebaseException)

يتم استدعاء هذه الطريقة استجابةً لطلب إثبات هوية غير صالح، مثل طلب يحدّد رقم هاتف أو رمز إثبات هوية غير صالح.

onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken)

هذه السمة اختيارية. يتم استدعاء هذه الطريقة بعد إرسال رمز التحقّق عبر رسالة SMS إلى رقم الهاتف المقدَّم.

عند استدعاء هذا الإجراء، تعرض معظم التطبيقات واجهة مستخدم تطلب من المستخدم كتابة رمز التحقّق الوارد في الرسالة القصيرة. (في الوقت نفسه، قد تكون عملية إثبات الملكية التلقائي جارية في الخلفية). بعد أن يكتب المستخدم رمز التحقّق، يمكنك استخدام رمز التحقّق ومعرّف التحقّق الذي تم تمريره إلى الطريقة لإنشاء عنصر PhoneAuthCredential، والذي يمكنك بدوره استخدامه لتسجيل دخول المستخدم. ومع ذلك، قد تنتظر بعض التطبيقات إلى أن يتم استدعاء onCodeAutoRetrievalTimeOut قبل عرض واجهة المستخدم الخاصة برمز التحقّق (لا يُنصح بذلك).

onCodeAutoRetrievalTimeOut(String verificationId)

هذه السمة اختيارية. يتم استدعاء هذا الإجراء بعد انقضاء مدة المهلة المحدّدة في verifyPhoneNumber بدون أن يتم تفعيل onVerificationCompleted أولاً. في الأجهزة التي لا تحتوي على شرائح SIM، يتم استدعاء هذه الطريقة على الفور لأنّه لا يمكن استرداد الرسائل القصيرة تلقائيًا.

تحظر بعض التطبيقات إدخال المستخدم إلى أن تنتهي مهلة التحقّق التلقائي، وبعدها فقط تعرض واجهة مستخدم تطلب من المستخدم كتابة رمز التحقّق من الرسالة القصيرة (لا يُنصح بذلك).

إنشاء عنصر PhoneAuthCredential

بعد أن يدخل المستخدم رمز التحقّق الذي أرسله Firebase إلى هاتفه، أنشئ عنصر PhoneAuthCredential باستخدام رمز التحقّق ومعرّف التحقّق الذي تم تمريره إلى معاودة الاتصال onCodeSent أو onCodeAutoRetrievalTimeOut. (عند استدعاء onVerificationCompleted، ستحصل على الكائن PhoneAuthCredential مباشرةً، لذا يمكنك تخطّي هذه الخطوة).

لإنشاء الكائن PhoneAuthCredential، استدعِ الدالة PhoneAuthProvider.getCredential:

Kotlin

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

Java

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

تسجيل دخول المستخدم

بعد الحصول على عنصر PhoneAuthCredential، سواء في دالة رد الاتصال 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"
  • كتابة اختبارات الدمج بدون أن يتم حظرها من خلال عمليات التحقّق من الأمان التي يتم تطبيقها عادةً على أرقام الهواتف الحقيقية في بيئة الإنتاج

يجب أن تستوفي أرقام الهواتف الوهمية المتطلبات التالية:

  1. تأكَّد من استخدام أرقام هواتف وهمية بالفعل وغير مستخدَمة من قبل. لا تسمح لك Firebase Authentication بتحديد أرقام هواتف حالية يستخدمها مستخدمون حقيقيون كأرقام اختبارية. أحد الخيارات هو استخدام أرقام تبدأ بالرقم 555 كأرقام هواتف اختبارية في الولايات المتحدة، على سبيل المثال: +1 650-555-3434
  2. يجب تنسيق أرقام الهواتف بشكل صحيح من حيث الطول والقيود الأخرى. وستخضع هذه الأرقام لعملية التحقّق نفسها التي يخضع لها رقم الهاتف الخاص بالمستخدم الحقيقي.
  3. يمكنك إضافة ما يصل إلى 10 أرقام هواتف للتطوير.
  4. استخدِم أرقام هواتف/رموز اختبار يصعب تخمينها وتغييرها بشكل متكرر.

إنشاء أرقام هواتف ورموز تحقّق وهمية

  1. في Firebase وحدة التحكّم، افتح قسم المصادقة.
  2. في علامة التبويب طريقة تسجيل الدخول، فعِّل "مزوّد خدمة الهاتف" إذا لم يسبق لك إجراء ذلك.
  3. افتح قائمة الأكورديون أرقام الهواتف المخصّصة للاختبار.
  4. أدخِل رقم الهاتف الذي تريد اختباره، مثل: +1 650-555-3434.
  5. أدخِل رمز التأكيد المكوّن من 6 أرقام لهذا الرقم المحدّد، مثلاً: 654321.
  6. أضِف الرقم. إذا دعت الحاجة، يمكنك حذف رقم الهاتف والرمز المرتبط به من خلال تمرير مؤشر الماوس فوق الصف المعنيّ والنقر على رمز المهملات.

الاختبار اليدوي

يمكنك البدء مباشرةً في استخدام رقم هاتف وهمي في تطبيقك. يتيح لك ذلك إجراء اختبار يدوي خلال مراحل التطوير بدون مواجهة مشاكل في الحصة أو الحدّ من السرعة. يمكنك أيضًا إجراء الاختبار مباشرةً من محاكي iOS أو محاكي Android بدون تثبيت "خدمات Google Play".

عند تقديم رقم الهاتف الوهمي وإرسال رمز التحقّق، لن يتم إرسال أي رسالة SMS فعلية. بدلاً من ذلك، عليك تقديم رمز التحقّق الذي تم ضبطه سابقًا لإكمال عملية تسجيل الدخول.

عند اكتمال عملية تسجيل الدخول، يتم إنشاء مستخدم Firebase باستخدام رقم الهاتف هذا. يتصرف المستخدم ويملك الخصائص نفسها التي يملكها مستخدم رقم الهاتف الحقيقي، ويمكنه الوصول إلى Realtime Database/Cloud Firestore والخدمات الأخرى بالطريقة نفسها. يحتوي رمز التعريف المميز الذي تم إنشاؤه خلال هذه العملية على التوقيع نفسه الذي يستخدمه مستخدم رقم الهاتف الحقيقي.

هناك خيار آخر وهو ضبط دور اختباري من خلال المطالبات المخصّصة لهؤلاء المستخدمين لتصنيفهم كمستخدمين مزيّفين إذا أردت فرض المزيد من القيود على إمكانية الوصول.

لتفعيل مسار reCAPTCHA يدويًا لأغراض الاختبار، استخدِم طريقة forceRecaptchaFlowForTesting().

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

اختبار الدمج

بالإضافة إلى الاختبار اليدوي، توفّر Firebase Authentication واجهات برمجة تطبيقات للمساعدة في كتابة اختبارات الدمج لاختبار مصادقة الهاتف. تؤدي واجهات برمجة التطبيقات هذه إلى إيقاف ميزة التحقّق من التطبيق من خلال إيقاف شرط reCAPTCHA في الويب والإشعارات الفورية الصامتة في iOS. ويتيح ذلك إجراء اختبارات التشغيل الآلي في هذه المسارات وتسهيل تنفيذها. بالإضافة إلى ذلك، تساعد هذه الأدوات في توفير إمكانية اختبار مسارات التحقّق الفوري على أجهزة Android.

على أجهزة Android، اتّصِل بـ setAppVerificationDisabledForTesting() قبل الاتصال بـ signInWithPhoneNumber. يؤدي ذلك إلى إيقاف ميزة إثبات ملكية التطبيق تلقائيًا، ما يتيح لك إدخال رقم الهاتف بدون الحاجة إلى حلّها يدويًا. حتى إذا تم إيقاف Play Integrity وreCAPTCHA، سيظل تعذُّر إكمال عملية تسجيل الدخول عند استخدام رقم هاتف حقيقي. لا يمكن استخدام سوى أرقام الهواتف الوهمية مع واجهة برمجة التطبيقات هذه.

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

سيؤدي الاتصال بالرقم verifyPhoneNumber باستخدام رقم وهمي إلى تشغيل معاودة الاتصال 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();