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

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

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

قبل ان تبدأ

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

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

مخاوف أمنية

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

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

تمكين تسجيل الدخول برقم الهاتف لمشروع Firebase الخاص بك

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

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

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

تمكين التحقق من التطبيق

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

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

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

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

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

ابدأ في تلقي الإشعارات الصامتة

لتمكين إشعارات APNs للاستخدام مع مصادقة Firebase:

  1. في Xcode، قم بتمكين الإشعارات المباشرة لمشروعك.
  2. قم بتحميل مفتاح مصادقة APNs الخاص بك إلى Firebase. إذا لم يكن لديك بالفعل مفتاح مصادقة APNs، فتأكد من إنشاء واحد في مركز أعضاء مطوري Apple .

    1. داخل مشروعك في وحدة تحكم Firebase، حدد رمز الترس، وحدد إعدادات المشروع ، ثم حدد علامة التبويب Cloud Messaging .

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

    3. استعرض وصولاً إلى الموقع الذي حفظت فيه مفتاحك، وحدده، ثم انقر فوق فتح . أضف معرف المفتاح للمفتاح (المتوفر في مركز أعضاء مطوري Apple ) وانقر فوق تحميل .

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

قم بإعداد التحقق من reCAPTCHA

لتمكين Firebase SDK من استخدام التحقق من reCAPTCHA:

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

      عند الانتهاء، يجب أن يبدو التكوين الخاص بك مشابهًا لما يلي (ولكن مع القيم الخاصة بالتطبيق):

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

إرسال رمز التحقق إلى هاتف المستخدم

لبدء تسجيل الدخول برقم الهاتف، قدم للمستخدم واجهة تطالبه بتقديم رقم هاتفه، ثم اتصل بـ verifyPhoneNumber(_:uiDelegate:completion:) لمطالبة Firebase بإرسال رمز المصادقة إلى هاتف المستخدم عبر الرسائل القصيرة:

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

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

  2. اتصل بـ verifyPhoneNumber(_:uiDelegate:completion:) لتمرير رقم هاتف المستخدم إليه.

    سويفت

    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 رسالة نصية قصيرة ثانية ما لم تنته مهلة الطلب الأصلي.

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

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

    سويفت

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

    ج موضوعية

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

    يمكنك الاستمرار في معرف التحقق بالطريقة التي تريدها. هناك طريقة بسيطة تتمثل في حفظ معرف التحقق باستخدام كائن NSUserDefaults :

    سويفت

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

    ج موضوعية

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

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

    سويفت

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

    ج موضوعية

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

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

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

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

  1. الحصول على رمز التحقق من المستخدم.
  2. قم بإنشاء كائن FIRPhoneAuthCredential من رمز التحقق ومعرف التحقق.

    سويفت

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

    ج موضوعية

    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. قم بتسجيل دخول المستخدم باستخدام كائن FIRPhoneAuthCredential :

    سويفت

    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. يوفر الاختبار باستخدام أرقام هواتف وهمية هذه الفوائد:

  • اختبر مصادقة رقم الهاتف دون استهلاك حصة الاستخدام الخاصة بك.
  • اختبار مصادقة رقم الهاتف دون إرسال رسالة نصية قصيرة فعلية.
  • قم بإجراء اختبارات متتالية باستخدام رقم الهاتف نفسه دون الاختناق. وهذا يقلل من خطر الرفض أثناء عملية مراجعة متجر التطبيقات إذا حدث أن استخدم المراجع نفس رقم الهاتف للاختبار.
  • يمكنك الاختبار بسهولة في بيئات التطوير دون أي جهد إضافي، مثل القدرة على التطوير في محاكي iOS أو محاكي Android بدون خدمات Google Play.
  • قم بكتابة اختبارات التكامل دون أن يتم حظرك بواسطة عمليات التحقق الأمني ​​التي يتم تطبيقها عادةً على أرقام الهواتف الحقيقية في بيئة الإنتاج.

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

  1. تأكد من استخدام أرقام هواتف وهمية بالفعل، وغير موجودة بالفعل. لا تسمح لك مصادقة Firebase بتعيين أرقام الهواتف الحالية التي يستخدمها المستخدمون الحقيقيون كأرقام اختبار. أحد الخيارات هو استخدام 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 واجهات برمجة التطبيقات للمساعدة في كتابة اختبارات التكامل لاختبار مصادقة الهاتف. تعمل واجهات برمجة التطبيقات هذه على تعطيل التحقق من التطبيق عن طريق تعطيل متطلبات reCAPTCHA في الويب وإشعارات الدفع الصامتة في نظام التشغيل iOS. وهذا يجعل اختبار الأتمتة ممكنًا في هذه التدفقات وأسهل في التنفيذ. بالإضافة إلى ذلك، فهي تساعد في توفير القدرة على اختبار تدفقات التحقق الفوري على Android.

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

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

سويفت

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;
    }];
}];

الملحق: استخدام تسجيل الدخول عبر الهاتف دون swizzling

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

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

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

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

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

سويفت

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

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

سويفت

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 إلى طريقة Auth 's canHandleURL(_:) .

سويفت

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

سويفت

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
  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<UIOpenURLContext *> *)URLContexts {
  for (UIOpenURLContext *urlContext in URLContexts) {
    [FIRAuth.auth canHandleURL:urlContext.url];
    // URL not auth related; it should be handled separately.
  }
}

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

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

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

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

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

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

سويفت

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

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