المصادقة مع Firebase على أنظمة Apple الأساسية باستخدام رقم هاتف

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

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

قبل البدء

  1. إذا لم يسبق لك ربط تطبيقك بمشروعك على Firebase، يمكنك إجراء ذلك من وحدة تحكّم Firebase.
  2. استخدِم Swift Package Manager لتثبيت تبعيات Firebase وإدارتها.

    1. في Xcode، مع فتح مشروع تطبيقك، انتقِل إلى ملف > إضافة حِزم.
    2. أضِف مستودع حزمة تطوير البرامج (SDK) لمنصّات Apple من Firebase عندما يُطلب منك ذلك:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. اختَر مكتبة Firebase Authentication.
    5. أضِف العلامة -ObjC إلى قسم رموز ربط أخرى في إعدادات الإنشاء الخاصة بالهدف.
    6. عند الانتهاء، سيبدأ Xcode تلقائيًا في حلّ ملفاتك المضمّنة وتنزيلها في الخلفية.

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

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

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

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

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

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

تفعيل ميزة "إثبات ملكية التطبيق"

لاستخدام مصادقة رقم الهاتف، يجب أن تتمكّن Firebase من التحقّق من أنّه تأتي طلبات تسجيل الدخول باستخدام رقم الهاتف من تطبيقك. وتتوفّر طريقتان لتحقيق ذلك:Firebase Authentication

  • إشعارات APNs الصامتة: عند تسجيل دخول مستخدم باستخدام رقم هاتفه لأول مرة على جهاز، تُرسِل Firebase Authentication رمزًا مميّزًا إلى الجهاز باستخدام إشعار دفع صامت. إذا تلقّى تطبيقك الإشعار من Firebase بنجاح، يمكن مواصلة تسجيل الدخول باستخدام رقم الهاتف.

    بالنسبة إلى الإصدار 8.0 من نظام التشغيل iOS والإصدارات الأحدث، لا تتطلّب الإشعارات الصامتة موافقة صريحة من العميل، وبالتالي لا تتأثر برفض العميل تلقّي إشعارات APNs في التطبيق. وبالتالي، لا يحتاج التطبيق إلى طلب إذن العميل لتلقّي إشعارات فورية عند تنفيذ مصادقة رقم الهاتف في Firebase.

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

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

بدء تلقّي إشعارات صامتة

لتفعيل إشعارات APNs لاستخدامها مع Firebase Authentication:

  1. في Xcode، فعِّل الإشعارات الفورية لمشروعك.
  2. حمِّل مفتاح مصادقة APNs إلى Firebase. إذا لم يكن لديك مفتاح مصادقة APNs، احرص على إنشاء مفتاح في Apple Developer Member Center.

    1. داخل مشروعك في وحدة تحكّم Firebase، انقر على رمز الترس، ثم على إعدادات المشروع، ثم على علامة التبويب الرسائل على السحابة الإلكترونية.

    2. في مفتاح مصادقة APNs ضمن إعدادات تطبيق iOS، انقر على الزر تحميل.

    3. انتقِل إلى المكان الذي حفظت فيه مفتاحك، واختَره، ثم انقر على فتح. أضِف معرّف المفتاح (متاحًا في Apple Developer Member Center) وانقر على تحميل.

    إذا كانت لديك شهادة APNs، يمكنك تحميل الشهادة بدلاً من ذلك.

  3. في Xcode، فعِّل ميزة "الأوضاع التي تعمل في الخلفية" لمشروعك، ثم ضَع علامة في مربّعات الاختيار الخاصة بحالَي الاسترداد في الخلفية والإشعارات عن بُعد.

إعداد اختبار التحقّق reCAPTCHA

لتفعيل حزمة تطوير البرامج (SDK) لمنصّة Firebase لاستخدام اختبار التحقّق من reCAPTCHA، اتّبِع الخطوات التالية:

  1. أضِف مخطّطات عناوين URL مخصّصة إلى مشروع Xcode:
    1. افتح إعدادات المشروع: انقر نقرًا مزدوجًا على اسم المشروع في عرض الشجرة على يمين الصفحة. اختَر تطبيقك من قسم الاستهدافات، ثم انقر على علامة التبويب المعلومات ووسِّع قسم أنواع عناوين URL.
    2. انقر على الزر + وأضِف رقم تعريف التطبيق المشفَّر كتنسيق عنوان URL. يمكنك العثور على رقم تعريف التطبيق المشفَّر في صفحة الإعدادات العامة في وحدة تحكُّم Firebase، في قسم تطبيقك على iOS. اترك الحقول الأخرى فارغة.

      عند الانتهاء، من المفترض أن تظهر الإعدادات على النحو التالي (ولكن مع القيم الخاصة بتطبيقك):

      لقطة شاشة لواجهة إعداد مخطّط عنوان URL المخصّص في Xcode
  2. اختياري: إذا كنت تريد تخصيص طريقة عرض التطبيق لملف SFSafariViewController عند عرض reCAPTCHA للمستخدم، أنشئ فئة مخصّصة تتوافق مع بروتوكول AuthUIDelegate، ثمّ أرسِلها إلى verifyPhoneNumber(_:uiDelegate:completion:).

إرسال رمز إثبات ملكية إلى هاتف المستخدم

لبدء عملية تسجيل الدخول باستخدام رقم الهاتف، عليك عرض واجهة على المستخدم تطلب منه تقديم رقم هاتفه، ثم الاتصال برقم verifyPhoneNumber(_:uiDelegate:completion:) لطلب أن تُرسِل Firebase رمز مصادقة إلى هاتف المستخدم من خلال رسالة قصيرة SMS:

  1. الحصول على رقم هاتف المستخدم

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

  2. اتصل بالرقم verifyPhoneNumber(_:uiDelegate:completion:) مع تضمين رقم هاتف المستخدم.
    SwiftObjective-C
    PhoneAuthProvider.provider()
      .verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
          if let error = error {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // Sign in using the verificationID and the code sent to the user
          // ...
      }
    [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput
                                            UIDelegate:nil
                                            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
      if (error) {
        [self showMessagePrompt:error.localizedDescription];
        return;
      }
      // Sign in using the verificationID and the code sent to the user
      // ...
    }];

    الطريقة verifyPhoneNumber هي طريقة قابلة للدخول المتكرّر: إذا تمّ استدعاؤها عدّة مرّات، مثلاً في طريقة onAppear لعرض معيّن، لن تُرسِل الطريقة verifyPhoneNumber رسالة SMS ثانية ما لم تنته مهلة الطلب الأصلي.

    عند الاتصال بالرقم verifyPhoneNumber(_:uiDelegate:completion:)، تُرسِل Firebase إشعارًا فوريًا بدون صوت إلى تطبيقك، أو تُطلِق تحدي reCAPTCHA على المستخدم. بعد أن يتلقّى تطبيقك الإشعار أو يُكمل المستخدم تحدّي reCAPTCHA، تُرسِل Firebase رسالة SMS تتضمّن رمز مصادقة إلى رقم الهاتف المحدّد وتُرسِل معرّف إثبات الهوية إلى دالة الإنجاز. ستحتاج إلى رمز التحقّق ومعرّف التحقّق لتسجيل دخول المستخدم.

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

    SwiftObjective-C
     // Change language code to french.
     Auth.auth().languageCode = "fr";
     // Change language code to french.
     [FIRAuth auth].languageCode = @"fr";
  3. احفظ رقم تعريف إثبات الهوية واستعده عند تحميل تطبيقك. من خلال إجراء ذلك، يمكنك التأكّد من أنّه لا يزال لديك معرّف إثبات هوية صالح إذا تم إغلاق تطبيقك قبل أن يكمل المستخدم عملية تسجيل الدخول (على سبيل المثال، أثناء التبديل إلى تطبيق الرسائل القصيرة).

    يمكنك الاحتفاظ بمستند تعريف الهوية بأي طريقة تريدها. يمكنك استخدام إحدى الطريقتَين التاليتَين: حفظ معرّف إثبات الهوية باستخدام العنصر NSUserDefaults:

    SwiftObjective-C
    UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:verificationID forKey:@"authVerificationID"];

    بعد ذلك، يمكنك استعادة القيمة المحفوظة:

    SwiftObjective-C
    let verificationID = UserDefaults.standard.string(forKey: "authVerificationID")
    NSString *verificationID = [defaults stringForKey:@"authVerificationID"];

إذا نجحت المكالمة إلى verifyPhoneNumber(_:uiDelegate:completion:) ، يمكنك مطالبة المستخدم بكتابة رمز التحقّق عند استلامه في رسالة SMS.

تسجيل دخول المستخدم باستخدام رمز إثبات الملكية

بعد أن يقدّم المستخدم لتطبيقك رمز التحقّق من رسالة SMS ، سجِّل دخول المستخدم من خلال إنشاء عنصر FIRPhoneAuthCredential من رمز التحقّق ورقم تعريف التحقّق وإرسال هذا العنصر إلى signInWithCredential:completion:.

  1. احصل على رمز التحقّق من المستخدم.
  2. أنشئ عنصرًا من النوع FIRPhoneAuthCredential من رمز التحقّق ومعرّف التحقّق.
    SwiftObjective-C
    let credential = PhoneAuthProvider.provider().credential(
      withVerificationID: verificationID,
      verificationCode: verificationCode
    )
    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. سجِّل دخول المستخدم باستخدام عنصر FIRPhoneAuthCredential:
    SwiftObjective-C
    Auth.auth().signIn(with: credential) { authResult, error in
        if let error = error {
          let authError = error as NSError
          if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue {
            // The user is a multi-factor user. Second factor challenge is required.
            let resolver = authError
              .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
            var displayNameString = ""
            for tmpFactorInfo in resolver.hints {
              displayNameString += tmpFactorInfo.displayName ?? ""
              displayNameString += " "
            }
            self.showTextInputPrompt(
              withMessage: "Select factor to sign in\n\(displayNameString)",
              completionBlock: { userPressedOK, displayName in
                var selectedHint: PhoneMultiFactorInfo?
                for tmpFactorInfo in resolver.hints {
                  if displayName == tmpFactorInfo.displayName {
                    selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo
                  }
                }
                PhoneAuthProvider.provider()
                  .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil,
                                     multiFactorSession: resolver
                                       .session) { verificationID, error in
                    if error != nil {
                      print(
                        "Multi factor start sign in failed. Error: \(error.debugDescription)"
                      )
                    } else {
                      self.showTextInputPrompt(
                        withMessage: "Verification code for \(selectedHint?.displayName ?? "")",
                        completionBlock: { userPressedOK, verificationCode in
                          let credential: PhoneAuthCredential? = PhoneAuthProvider.provider()
                            .credential(withVerificationID: verificationID!,
                                        verificationCode: verificationCode!)
                          let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator
                            .assertion(with: credential!)
                          resolver.resolveSignIn(with: assertion!) { authResult, error in
                            if error != nil {
                              print(
                                "Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
                              )
                            } else {
                              self.navigationController?.popViewController(animated: true)
                            }
                          }
                        }
                      )
                    }
                  }
              }
            )
          } else {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // ...
          return
        }
        // User is signed in
        // ...
    }
    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult,
                                           NSError * _Nullable error) {
        if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
          FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
          NSMutableString *displayNameString = [NSMutableString string];
          for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
            [displayNameString appendString:tmpFactorInfo.displayName];
            [displayNameString appendString:@" "];
          }
          [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                               completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
           FIRPhoneMultiFactorInfo* selectedHint;
           for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
             if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
               selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
             }
           }
           [FIRPhoneAuthProvider.provider
            verifyPhoneNumberWithMultiFactorInfo:selectedHint
            UIDelegate:nil
            multiFactorSession:resolver.session
            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
              if (error) {
                [self showMessagePrompt:error.localizedDescription];
              } else {
                [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                     completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
                 FIRPhoneAuthCredential *credential =
                     [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                                  verificationCode:verificationCode];
                 FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
                 [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
                   if (error) {
                     [self showMessagePrompt:error.localizedDescription];
                   } else {
                     NSLog(@"Multi factor finanlize sign in succeeded.");
                   }
                 }];
               }];
              }
            }];
         }];
        }
      else if (error) {
        // ...
        return;
      }
      // User successfully signed in. Get user data from the FIRUser object
      if (authResult == nil) { return; }
      FIRUser *user = authResult.user;
      // ...
    }];

إجراء الاختبار باستخدام أرقام هواتف خيالية

يمكنك إعداد أرقام هواتف خيالية لاستخدامها في مرحلة التطوير من خلال وحدة تحكّم 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 والخدمات الأخرى بالطريقة نفسها. يحتوي رمز التعريف الذي تم إنشاؤه أثناء هذه العملية على التوقيع نفسه المستخدَم في رمز تعريف المستخدم الذي يستخدم رقم هاتف حقيقيًا.

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

اختبار الدمج

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

على نظام التشغيل iOS، يجب ضبط الإعداد appVerificationDisabledForTesting على TRUE قبل استدعاء verifyPhoneNumber. تتم معالجة ذلك بدون الحاجة إلى أي رمز مميّز لخدمات APN أو إرسال إشعارات فورية صامتة في الخلفية، ما يسهّل اختباره في المحاكي. سيؤدي ذلك أيضًا إلى إيقاف مسار الردّ الاحتياطي في reCAPTCHA.

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

SwiftObjective-C
let phoneNumber = "+16505554567"

// This test verification code is specified for the given test phone number in the developer console.
let testVerificationCode = "123456"

Auth.auth().settings.isAppVerificationDisabledForTesting = TRUE
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) {
                                                            verificationID, error in
    if (error) {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signInAndRetrieveData(with: credential) { authData, error in
      if (error) {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authData.user
    }];
}];
NSString *phoneNumber = @"+16505554567";

// This test verification code is specified for the given test phone number in the developer console.
NSString *testVerificationCode = @"123456";

[FIRAuth auth].settings.appVerificationDisabledForTesting = YES;
[[FIRPhoneAuthProvider provider] verifyPhoneNumber:phoneNumber
                                        completion:^(NSString *_Nullable verificationID,
                                                     NSError *_Nullable error) {
    if (error) {
      // Handles error
      [self handleError:error];
      return;
    }
    FIRAuthCredential *credential =
        [FIRPhoneAuthProvider credentialWithVerificationID:verificationID
                                          verificationCode:testVerificationCode];
    [FIRAuth auth] signInWithAndRetrieveDataWithCredential:credential
                                                completion:^(FIRUser *_Nullable user,
                                                             NSError *_Nullable error) {
      if (error) {
        // Handles error
        [self handleError:error];
        return;
      }
      _user = user;
    }];
}];

الملحق: استخدام ميزة "تسجيل الدخول باستخدام الهاتف" بدون تبديل المحتوى

يستخدم Firebase Authentication طريقة تبديل الطريقة للحصول تلقائيًا على رمز عبور APNs لتطبيقك، ومعالجة الإشعارات الفورية الصامتة التي يرسلها Firebase إلى تطبيقك، واعتراض إعادة التوجيه إلى المخطط المخصّص تلقائيًا من صفحة إثبات صحة reCAPTCHA أثناء إثبات الملكية.

إذا كنت تفضّل عدم استخدام ميزة "تبديل الرموز البرمجية"، يمكنك إيقافها عن طريق إضافة العلامة FirebaseAppDelegateProxyEnabled إلى ملف Info.plist في تطبيقك و ضبطها على NO. يُرجى العلم أنّ ضبط هذه العلامة على NO يؤدي أيضًا إلى إيقاف عملية التبديل في منتجات Firebase الأخرى، بما في ذلك Firebase Cloud Messaging.

في حال إيقاف عملية التبديل، يجب ضبط الرمز المميّز لجهاز APNs و الإشعارات الفورية وعنوان URL لإعادة التوجيه الخاص بالمخطّط المخصّص بشكل صريح على Firebase Authentication.

إذا كنت بصدد إنشاء تطبيق SwiftUI، عليك أيضًا تمرير رمز تنشيط الجهاز في APNs والإشعارات الفورية وعنوان URL لإعادة التوجيه الخاص بالمخطط المخصّص إلى Firebase Authentication.

للحصول على رمز تنشيط جهاز APNs، نفِّذ الطريقة application(_:didRegisterForRemoteNotificationsWithDeviceToken:) ، واضبط رمز تنشيط الجهاز على الطريقة setAPNSToken(_:type:) في Auth.

SwiftObjective-C
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  // Pass device token to auth
  Auth.auth().setAPNSToken(deviceToken, type: .unknown)

  // Further handling of the device token if needed by the app
  // ...
}
- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  // Pass device token to auth.
  [[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];
  // Further handling of the device token if needed by the app.
}

لمعالجة الإشعارات الفورية، في الأسلوب application(_:didReceiveRemoteNotification:fetchCompletionHandler:): ، تحقّق من الإشعارات ذات الصلة بمصادقة Firebase من خلال استدعاء الأسلوب canHandleNotification(_:) في Auth.

SwiftObjective-C
func application(_ application: UIApplication,
    didReceiveRemoteNotification notification: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  if Auth.auth().canHandleNotification(notification) {
    completionHandler(.noData)
    return
  }
  // This notification is not auth related; it should be handled separately.
}
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)notification
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // Pass notification to auth and check if they can handle it.
  if ([[FIRAuth auth] canHandleNotification:notification]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return;
  }
  // This notification is not auth related; it should be handled separately.
}

لمعالجة عنوان URL المخصّص لإعادة التوجيه، نفِّذ الأسلوب application(_:open:options:)، وفيه، مرِّر عنوان URL إلى الأسلوب canHandleURL(_:) في Auth.

SwiftObjective-C
func application(_ application: UIApplication, open url: URL,
    options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
  if Auth.auth().canHandle(url) {
    return true
  }
  // URL not auth related; it should be handled separately.
}
- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  if ([[FIRAuth auth] canHandleURL:url]) {
    return YES;
  }
  // URL not auth related; it should be handled separately.
}

إذا كنت تستخدم SwiftUI أو UISceneDelegate، يمكنك تنفيذ الأسلوب scene(_:openURLContexts:) لمعالجة عنوان URL لإعادة التوجيه، ويجب تمرير عنوان URL إلى الأسلوب canHandleURL(_:) في Auth.

SwiftObjective-C
func scene(_ scene: UIScene, openURLContexts URLContexts: Set&ltUIOpenURLContext&gt) {
  for urlContext in URLContexts {
      let url = urlContext.url
      _ = Auth.auth().canHandle(url)
  }
  // URL not auth related; it should be handled separately.
}
- (void)scene:(UIScene *)scene openURLContexts:(NSSet&ltUIOpenURLContext *&gt *)URLContexts {
  for (UIOpenURLContext *urlContext in URLContexts) {
    [FIRAuth.auth canHandleURL:urlContext.url];
    // URL not auth related; it should be handled separately.
  }
}

الخطوات التالية

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

  • في تطبيقاتك، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من العنصر User . راجِع إدارة المستخدمين.

  • في Firebase Realtime Database وCloud Storage قواعد الأمان، يمكنك الحصول على معرّف المستخدم الفريد للمستخدم الذي سجّل الدخول من متغيّر auth، واستخدامه للتحكّم في البيانات التي يمكن للمستخدم الوصول إليها.

يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام عدة موفّري مصادقة من خلال ربط بيانات اعتماد موفّر المصادقة بحساب مستخدمحالٍ.

لتسجيل خروج مستخدم، اتصل بالرقم signOut:.

SwiftObjective-C
let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

يمكنك أيضًا إضافة رمز لمعالجة الأخطاء في النطاق الكامل لأخطاء مصادقة العميل. راجِع مقالة معالجة الأخطاء.