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

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

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

قبل البدء

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

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

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

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

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

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

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

  1. في وحدة تحكّم Firebaseconsole، افتح قسم المصادقة.
  2. في صفحة طريقة تسجيل الدخول ، فعِّل طريقة تسجيل الدخول رقم الهاتف.
  3. في صفحة الإعدادات ، ضَع سياسة بشأن المناطق التي تريد السماح بإرسال رسائل SMS إليها أو رفض إرسالها إليها. بالنسبة إلى المشاريع الجديدة، لا تسمح السياسة التلقائية بأي مناطق.

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

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

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

    بالنسبة إلى iOS 8.0 والإصدارات الأحدث، لا تتطلّب الإشعارات الصامتة موافقة صريحة من المستخدم، وبالتالي لا تتأثر برفض المستخدم تلقّي إشعارات 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:) لطلب إرسال رمز مصادقة إلى هاتف المستخدم عن طريق الرسائل القصيرة SMS من Firebase:

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

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

  2. استدعِ verifyPhoneNumber(_:uiDelegate:completion:)، ومرِّر إليه رقم هاتف المستخدم.

    Swift

    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
          // ...
      }

    Objective-C

    [[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 لعرض، لن ترسل الط0ريقة verifyPhoneNumber رسالة SMS ثانية إلا إذا انتهت مهلة الطلب الأصلي.

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

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

    Swift

     // Change language code to french.
     Auth.auth().languageCode = "fr";

    Objective-C

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

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

    Swift

    UserDefaults.standard.set(verificationID, forKey: "authVerificationID")

    Objective-C

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:verificationID forKey:@"authVerificationID"];

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

    Swift

    let verificationID = UserDefaults.standard.string(forKey: "authVerificationID")

    Objective-C

    NSString *verificationID = [defaults stringForKey:@"authVerificationID"];

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

تسجيل دخول المستخدم باستخدام رمز التحقّق

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

  1. احصل على رمز التحقّق من المستخدم.
  2. أنشِئ عنصر FIRPhoneAuthCredential من رمز التحقّق ورقم تعريف التحقّق.

    Swift

    let credential = PhoneAuthProvider.provider().credential(
      withVerificationID: verificationID,
      verificationCode: verificationCode
    )

    Objective-C

    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. سجِّل دخول المستخدم باستخدام العنصر FIRPhoneAuthCredential:

    Swift

    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
        // ...
    }

    Objective-C

    [[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 فعلية.
  • أجرِ اختبارات متتالية باستخدام رقم الهاتف نفسه بدون أن يتم تقييدك. يقلّل ذلك من خطر الرفض أثناء عملية مراجعة App Store إذا استخدم المراجع رقم الهاتف نفسه للاختبار.
  • اختبِر بسهولة في بيئات التطوير بدون أي جهد إضافي، مثل إمكانية التطوير في محاكي 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 والخدمات الأخرى بالطريقة نفسها. يتضمّن رمز التعريف الذي يتم إنشاؤه أثناء هذه العملية التوقيع نفسه الذي يتضمّنه رمز التعريف الخاص بمستخدم رقم الهاتف الحقيقي.

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

اختبار التكامل

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

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

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

Swift

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 let error = error {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signIn(with: credential) { authResult, error in
      if let error = error {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authResult.user
    };
};

Objective-C

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.

Swift

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
  // ...
}

Objective-C

- (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 عن طريق استدعاء Auth's canHandleNotification(_:)

Swift

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.
}

Objective-C

- (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.

Swift

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.
}

Objective-C

- (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، للتعامل مع عنوان URL لإعادة التوجيه، نفِّذ الطريقة scene(_:openURLContexts:)، ومرِّر عنوان URL إلى طريقة canHandleURL(_:) في Auth.

Swift

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.
}

Objective-C

- (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:.

Swift

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

Objective-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

قد تحتاج أيضًا إلى إضافة رمز للتعامل مع الأخطاء من أجل النطاق الكامل لأخطاء المصادقة. يُرجى الاطّلاع على التعامل مع الأخطاء.