احراز هویت با Firebase در پلتفرم های اپل با استفاده از شماره تلفن

می‌توانید از Firebase Authentication برای ورود کاربر با ارسال پیامک به تلفن کاربر استفاده کنید. کاربر با استفاده از کد یکبار مصرف موجود در پیام اس ام اس وارد سیستم می شود.

ساده ترین راه برای افزودن ورود به سیستم با شماره تلفن به برنامه خود استفاده از FirebaseUI است که شامل یک ویجت ورود به سیستم است که جریان های ورود به سیستم را برای ورود به شماره تلفن، و همچنین ورود مبتنی بر رمز عبور و ورود به سیستم را اجرا می کند. -در این سند نحوه پیاده‌سازی جریان ورود به سیستم شماره تلفن را با استفاده از Firebase SDK توضیح می‌دهد.

قبل از شروع

  1. اگر هنوز برنامه خود را به پروژه Firebase متصل نکرده اید، این کار را از کنسول Firebase انجام دهید.
  2. برای نصب و مدیریت وابستگی های Firebase از Swift Package Manager استفاده کنید.

    1. در Xcode، با باز بودن پروژه برنامه، به File > Add Packages بروید.
    2. هنگامی که از شما خواسته شد، مخزن SDK پلتفرم های Apple Firebase را اضافه کنید:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. کتابخانه Firebase Authentication انتخاب کنید.
    5. پرچم -ObjC را به بخش Other Linker Flags تنظیمات ساخت هدف خود اضافه کنید.
    6. پس از اتمام، Xcode به طور خودکار شروع به حل و دانلود وابستگی های شما در پس زمینه می کند.

نگرانی های امنیتی

احراز هویت تنها با استفاده از یک شماره تلفن، در عین راحتی، امنیت کمتری نسبت به سایر روش‌های موجود دارد، زیرا داشتن شماره تلفن به راحتی بین کاربران قابل انتقال است. همچنین، در دستگاه‌هایی با نمایه‌های کاربری متعدد، هر کاربری که می‌تواند پیامک دریافت کند، می‌تواند با استفاده از شماره تلفن دستگاه وارد حساب کاربری شود.

اگر از ورود بر اساس شماره تلفن در برنامه خود استفاده می‌کنید، باید آن را در کنار روش‌های ورود امن‌تر ارائه دهید و کاربران را از معاوضه‌های امنیتی استفاده از ورود به سیستم با شماره تلفن مطلع کنید.

ورود به سیستم شماره تلفن را برای پروژه Firebase خود فعال کنید

برای ورود کاربران از طریق پیامک، ابتدا باید روش ورود شماره تلفن را برای پروژه Firebase خود فعال کنید:

  1. در کنسول Firebase ، بخش Authentication را باز کنید.
  2. در صفحه Sign-in Method ، روش ورود شماره تلفن را فعال کنید.

تأیید برنامه را فعال کنید

برای استفاده از احراز هویت شماره تلفن، Firebase باید بتواند تأیید کند که درخواست‌های ورود به سیستم شماره تلفن از برنامه شما می‌آیند. دو راه وجود دارد که Firebase Authentication این کار را انجام می دهد:

  • اعلان‌های APN بی‌صدا : وقتی کاربر را برای اولین بار با شماره تلفنش در دستگاهی وارد می‌کنید، Firebase Authentication با استفاده از یک اعلان فشار بی‌صدا، رمزی را به دستگاه ارسال می‌کند. اگر برنامه شما با موفقیت اعلان را از Firebase دریافت کرد، ورود به سیستم با شماره تلفن می‌تواند ادامه یابد.

    برای iOS 8.0 و جدیدتر، اعلان‌های بی‌صدا نیازی به رضایت صریح کاربر ندارند و بنابراین توسط کاربر که از دریافت اعلان‌های APN در برنامه خودداری می‌کند، تأثیری نمی‌پذیرد. بنابراین، برنامه نیازی به درخواست مجوز کاربر برای دریافت اعلان‌های فشار هنگام اجرای احراز هویت شماره تلفن Firebase ندارد.

  • تأیید reCAPTCHA : در صورتی که ارسال یا دریافت اعلان فشار بی‌صدا امکان‌پذیر نباشد، مانند زمانی که کاربر به‌روزرسانی پس‌زمینه را برای برنامه شما غیرفعال کرده است، یا هنگام آزمایش برنامه شما در شبیه‌ساز iOS، Firebase Authentication از تأیید reCAPTCHA برای تکمیل تلفن استفاده می‌کند. جریان ورود به سیستم چالش reCAPTCHA اغلب می تواند بدون نیاز به حل چیزی توسط کاربر تکمیل شود.

هنگامی که اعلان‌های فشار بی‌صدا به درستی پیکربندی شوند، تنها درصد بسیار کمی از کاربران جریان reCAPTCHA را تجربه خواهند کرد. با این وجود، باید اطمینان حاصل کنید که ورود به سیستم شماره تلفن به درستی عمل می‌کند، خواه اعلان‌های فشار بی‌صدا در دسترس باشند یا نباشند.

شروع به دریافت اعلان‌های بی‌صدا کنید

برای فعال کردن اعلان‌های APN برای استفاده با Firebase Authentication :

  1. در Xcode، اعلان‌های فشاری را برای پروژه خود فعال کنید .
  2. کلید احراز هویت APN خود را در Firebase آپلود کنید. اگر از قبل یک کلید تأیید اعتبار APN ندارید، مطمئن شوید که در مرکز اعضای برنامه‌نویس Apple ایجاد کرده‌اید.

    1. در داخل پروژه خود در کنسول Firebase ، نماد چرخ دنده را انتخاب کنید، تنظیمات پروژه را انتخاب کنید و سپس برگه Cloud Messaging را انتخاب کنید.

    2. در کلید احراز هویت APN در پیکربندی برنامه iOS ، روی دکمه آپلود کلیک کنید.

    3. به مکانی که کلید خود را در آن ذخیره کرده اید بروید، آن را انتخاب کنید و روی Open کلیک کنید. شناسه کلید را برای کلید اضافه کنید (در مرکز اعضای برنامه نویس اپل موجود است) و روی آپلود کلیک کنید.

    اگر قبلاً یک گواهی APN دارید، می‌توانید گواهی را به جای آن آپلود کنید.

  3. در Xcode، قابلیت Background Modes را برای پروژه خود فعال کنید و سپس چک باکس های حالت های Background Fetch و Remote notifications را انتخاب کنید.

تأیید reCAPTCHA را تنظیم کنید

برای فعال کردن Firebase SDK برای استفاده از تأیید reCAPTCHA:

  1. طرح های URL سفارشی را به پروژه Xcode خود اضافه کنید:
    1. پیکربندی پروژه خود را باز کنید: روی نام پروژه در نمای درختی سمت چپ دوبار کلیک کنید. برنامه خود را از بخش TARGETS انتخاب کنید، سپس برگه Info را انتخاب کنید و بخش URL Types را گسترش دهید.
    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
          // ...
      }

    هدف-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 یک view، روش verifyPhoneNumber پیامک دومی ارسال نمی‌کند مگر اینکه زمان درخواست اصلی تمام شده باشد.

    وقتی با verifyPhoneNumber(_:uiDelegate:completion:) تماس می‌گیرید، Firebase یک اعلان فشار بی‌صدا به برنامه شما ارسال می‌کند یا یک چالش reCAPTCHA را برای کاربر ارسال می‌کند. پس از اینکه برنامه شما اعلان را دریافت کرد یا کاربر چالش reCAPTCHA را کامل کرد، Firebase یک پیام اس ام اس حاوی کد احراز هویت به شماره تلفن مشخص شده ارسال می کند و یک شناسه تأیید را به عملکرد تکمیل شما ارسال می کند. برای ورود کاربر به کد تأیید و شناسه تأیید نیاز دارید.

    پیام اس ام اس ارسال شده توسط Firebase همچنین می تواند با تعیین زبان تأیید از طریق ویژگی languageCode در نمونه Auth شما، بومی سازی شود.

    سویفت

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

    هدف-C

     // Change language code to french.
     [FIRAuth auth].languageCode = @"fr";
  3. شناسه تأیید را ذخیره کنید و زمانی که برنامه شما بارگیری شد، آن را بازیابی کنید. با انجام این کار، می‌توانید اطمینان حاصل کنید که اگر برنامه شما قبل از تکمیل جریان ورود به سیستم (به عنوان مثال، در حین جابجایی به برنامه پیامک) برنامه شما خاتمه یابد، همچنان یک شناسه تأیید معتبر دارید.

    شما می توانید شناسه تأیید را هر طور که می خواهید حفظ کنید. یک راه ساده این است که شناسه تأیید را با شی NSUserDefaults ذخیره کنید:

    سویفت

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

    هدف-C

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

    سپس، می توانید مقدار ذخیره شده را بازیابی کنید:

    سویفت

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

    هدف-C

    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
    )

    هدف-C

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

    هدف-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 تنظیم کنید. آزمایش با شماره تلفن های خیالی این مزایا را به همراه دارد:

  • احراز هویت شماره تلفن را بدون مصرف سهمیه استفاده خود آزمایش کنید.
  • احراز هویت شماره تلفن را بدون ارسال پیام کوتاه واقعی آزمایش کنید.
  • تست های متوالی را با همان شماره تلفن بدون دریچه گاز انجام دهید. اگر بازبین از همان شماره تلفن برای آزمایش استفاده کند، این خطر رد شدن را در طول فرآیند بررسی فروشگاه App به حداقل می‌رساند.
  • به راحتی در محیط های توسعه و بدون هیچ تلاش اضافی، مانند توانایی توسعه در شبیه ساز iOS یا شبیه ساز اندروید بدون خدمات Google Play، تست کنید.
  • تست‌های یکپارچه‌سازی را بدون مسدود شدن توسط بررسی‌های امنیتی که معمولاً روی شماره‌های تلفن واقعی در یک محیط تولید اعمال می‌شود، بنویسید.

شماره تلفن های خیالی باید این شرایط را داشته باشند:

  1. مطمئن شوید که از شماره‌های تلفنی استفاده می‌کنید که واقعاً تخیلی هستند و قبلاً وجود ندارند. Firebase Authentication به شما اجازه نمی دهد شماره تلفن های موجود مورد استفاده توسط کاربران واقعی را به عنوان شماره آزمایشی تنظیم کنید. یکی از گزینه ها استفاده از 555 شماره پیشوند به عنوان شماره تلفن آزمایشی ایالات متحده است، به عنوان مثال: +1 650-555-3434
  2. شماره تلفن ها باید از نظر طول و سایر محدودیت ها به درستی قالب بندی شوند. آنها همچنان از اعتبار سنجی مشابه شماره تلفن یک کاربر واقعی برخوردار خواهند بود.
  3. می توانید حداکثر 10 شماره تلفن برای توسعه اضافه کنید.
  4. از شماره‌ها/کدهای تلفن آزمایشی استفاده کنید که حدس زدن آن‌ها سخت است و مرتباً آن‌ها را تغییر دهید.

شماره تلفن های خیالی و کدهای تأیید را ایجاد کنید

  1. در کنسول Firebase ، بخش Authentication را باز کنید.
  2. اگر قبلاً این کار را نکرده‌اید، در برگه روش ورود به سیستم ، ارائه‌دهنده تلفن را فعال کنید.
  3. منوی شماره تلفن برای آزمایش آکاردئون را باز کنید.
  4. شماره تلفنی را که می‌خواهید آزمایش کنید وارد کنید، به عنوان مثال: +1 650-555-3434 .
  5. کد تأیید 6 رقمی آن شماره خاص را وارد کنید، به عنوان مثال: 654321 .
  6. عدد را اضافه کنید . در صورت نیاز، می‌توانید شماره تلفن و کد آن را با نگه داشتن ماوس روی ردیف مربوطه و کلیک کردن روی نماد حذف‌شده حذف کنید.

تست دستی

می توانید مستقیماً از یک شماره تلفن خیالی در برنامه خود استفاده کنید. این به شما این امکان را می‌دهد تا تست‌های دستی را در طول مراحل توسعه انجام دهید، بدون اینکه درگیر مشکلات سهمیه یا throttling شوید. همچنین می‌توانید مستقیماً از شبیه‌ساز iOS یا شبیه‌ساز اندروید بدون نصب سرویس‌های Google Play آزمایش کنید.

وقتی شماره تلفن ساختگی را ارائه می کنید و کد تأیید را ارسال می کنید، هیچ پیامکی واقعی ارسال نمی شود. در عوض، برای تکمیل ورود به سیستم، باید کد تأیید قبلی پیکربندی شده را ارائه کنید.

با تکمیل ورود به سیستم، یک کاربر Firebase با آن شماره تلفن ایجاد می شود. کاربر رفتار و ویژگی های یک کاربر شماره تلفن واقعی را دارد و می تواند به همان روش به Realtime Database / Cloud Firestore و سایر خدمات دسترسی داشته باشد. رمز شناسه ای که در طول این فرآیند ضرب شده است، امضای یک کاربر شماره تلفن واقعی را دارد.

گزینه دیگر این است که یک نقش آزمایشی از طریق ادعاهای سفارشی روی این کاربران تنظیم کنید تا اگر می خواهید دسترسی را محدودتر کنید، آنها را به عنوان کاربران جعلی متمایز کنید.

تست یکپارچه سازی

علاوه بر آزمایش دستی، Firebase Authentication API هایی را برای کمک به نوشتن تست های یکپارچه سازی برای تست احراز هویت تلفن ارائه می دهد. این APIها با غیرفعال کردن الزامات reCAPTCHA در وب و اعلان‌های فشار بی‌صدا در iOS، تأیید برنامه را غیرفعال می‌کنند. این امر آزمایش اتوماسیون را در این جریان ها ممکن می کند و پیاده سازی آن را آسان تر می کند. علاوه بر این، آنها به ارائه توانایی آزمایش جریان های تأیید فوری در Android کمک می کنند.

در iOS، تنظیمات appVerificationDisabledForTesting باید قبل از تماس با verifyPhoneNumber روی TRUE تنظیم شود. این بدون نیاز به هیچ توکن APN یا ارسال اعلان‌های فشار بی‌صدا در پس‌زمینه پردازش می‌شود و آزمایش را در شبیه‌ساز آسان‌تر می‌کند. این همچنین جریان بازگشتی reCAPTCHA را غیرفعال می کند.

توجه داشته باشید که وقتی تأیید برنامه غیرفعال است، با استفاده از یک شماره تلفن غیرتخیلی وارد سیستم نمی‌شوید. فقط از شماره تلفن‌های خیالی می‌توان با این API استفاده کرد.

سویفت

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

هدف-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 از روش Swizzling استفاده می‌کند تا به‌طور خودکار توکن APN برنامه شما را دریافت کند، اعلان‌های فشار بی‌صدا را که Firebase به برنامه شما ارسال می‌کند، مدیریت کند و به‌طور خودکار تغییر مسیر طرح سفارشی را از صفحه تأیید reCAPTCHA در حین تأیید قطع کند.

اگر ترجیح می‌دهید از Swizzling استفاده نکنید، می‌توانید با افزودن پرچم FirebaseAppDelegateProxyEnabled به فایل Info.plist برنامه خود و تنظیم آن روی NO ، آن را غیرفعال کنید. توجه داشته باشید که تنظیم این پرچم روی NO باعث غیرفعال شدن چرخش برای سایر محصولات Firebase، از جمله Firebase Cloud Messaging می‌شود.

اگر swizzling را غیرفعال کنید، باید به صراحت رمز دستگاه APN، اعلان‌های فشاری و طرح سفارشی URL را به Firebase Authentication هدایت کنید.

اگر در حال ساخت یک برنامه SwiftUI هستید، باید به صراحت توکن دستگاه APN، اعلان‌های فشار و طرح سفارشی URL را به Firebase Authentication هدایت کنید.

برای به دست آوردن توکن دستگاه APNs، متد application(_:didRegisterForRemoteNotificationsWithDeviceToken:) را پیاده سازی کنید و در آن، توکن دستگاه را به متد setAPNSToken(_:type:) Auth منتقل کنید.

سویفت

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

هدف-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 را با فراخوانی روش canHandleNotification(_:) Auth بررسی کنید.

سویفت

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

هدف-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 ارسال کنید.

سویفت

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

هدف-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 ارسال کنید.

سویفت

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

هدف-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: .

سویفت

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

هدف-C

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

همچنین ممکن است بخواهید کد رسیدگی به خطا را برای طیف کامل خطاهای احراز هویت اضافه کنید. به رسیدگی به خطاها مراجعه کنید.