المصادقة من خلال 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:33.7.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:23.1.0")
    }
    هل تبحث عن وحدة مكتبة خاصة بلغة Kotlin؟ اعتبارًا من تشرين الأول (أكتوبر) 2023 (Firebase BoM 32.5.0)، يمكن لمطوّري Kotlin وJava الاعتماد على وحدة المكتبة الرئيسية (للاطّلاع على التفاصيل، راجِع الأسئلة الشائعة حول هذه المبادرة).
  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 في مشروعك. تتوفّر ميزة "التأكّد من سلامة التطبيقات" في الإصدار 21.2.0 أو إصدار أحدث من حزمة تطوير البرامج (SDK) لنظام التشغيل Authentication (الإصدار 31.4.0 أو إصدار أحدث من حزمة تطوير البرامج (SDK) لنظام التشغيل Firebase BoM).

    لاستخدام ميزة 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 لإثبات الملكية، وسيتم تطبيق رسوم رسائل SMS العادية.

بعد ذلك، نقْل رقم هاتفه إلى PhoneAuthProvider.verifyPhoneNumber لطلب Firebase verifying the user's phone number. على سبيل المثال:

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 في Activity واستعدّ العلامة في onRestoreInstanceState. أخيرًا، في onStart method لنشاطك، تحقّق مما إذا كانت عملية إثبات الملكية قيد التقدّم، وإذا كان الأمر كذلك، اتصل بـ verifyPhoneNumber مرة أخرى. احرص على إزالة العلامة عند اكتمال عملية التحقّق أو تعذّرها (راجِع الاستدعاءات لتأكيد عملية التحقّق).

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

يمكن أيضًا ترجمة رسالة SMS التي ترسلها Firebase من خلال تحديد لغة ملف تعريف الاعتماد باستخدام طريقة setLanguageCode في مثيل ملف تعريف الاعتماد.

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 الذي تم تمريره إلى PhoneAuthCredential callback من أجل تسجيل دخول المستخدم.

onVerificationFailed(FirebaseException)

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

onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken)

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

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

onCodeAutoRetrievalTimeOut(String verificationId)

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

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

إنشاء عنصر 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".

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

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

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

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

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

اختبار الدمج

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

على جهاز Android، اتصل بالرقم setAppVerificationDisabledForTesting() قبل المكالمة على الرقم signInWithPhoneNumber. يؤدي ذلك إلى إيقاف ميزة إثبات ملكية التطبيق تلقائيًا، مما يتيح لك إرسال رقم الهاتف بدون حلّه يدويًا. حتى إذا كانت ميزتا "سلامة Play" و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();