ตรวจสอบสิทธิ์ด้วย Firebase บนแพลตฟอร์ม Apple โดยใช้หมายเลขโทรศัพท์

คุณสามารถใช้ Firebase Authentication เพื่อลงชื่อเข้าใช้ผู้ใช้โดยส่งข้อความ SMS ไปยังโทรศัพท์ของผู้ใช้ โดยผู้ใช้จะลงชื่อเข้าใช้โดยใช้รหัสแบบใช้ครั้งเดียวที่อยู่ในข้อความ SMS

วิธีที่ง่ายที่สุดในการเพิ่มการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์ลงในแอปคือการใช้ FirebaseUI ซึ่งมีวิดเจ็ตการลงชื่อเข้าใช้แบบดร็อปอินที่ใช้ขั้นตอนการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์ รวมถึงการลงชื่อเข้าใช้ด้วยรหัสผ่านและการลงชื่อเข้าใช้แบบรวมศูนย์ เอกสารนี้อธิบายวิธีใช้ขั้นตอนการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์โดยใช้ Firebase SDK

ก่อนเริ่มต้น

  1. หากยังไม่ได้เชื่อมต่อแอปกับโปรเจ็กต์ Firebase ให้ดำเนินการจาก Firebaseคอนโซล
  2. ใช้ Swift Package Manager เพื่อติดตั้งและจัดการทรัพยากร Dependency ของ Firebase

    1. เปิดโปรเจ็กต์แอปใน Xcode แล้วไปที่ File > Add Packages
    2. เมื่อได้รับข้อความแจ้ง ให้เพิ่มที่เก็บ Firebase Apple Platforms SDK ดังนี้
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. เลือกไลบรารี Firebase Authentication
    5. เพิ่มแฟล็ก -ObjC ลงในส่วน Other Linker Flags ของการตั้งค่าบิลด์ของเป้าหมาย
    6. เมื่อเสร็จแล้ว Xcode จะเริ่มจับคู่ข้อมูลและดาวน์โหลด ทรัพยากร Dependency ในเบื้องหลังโดยอัตโนมัติ

ข้อกังวลด้านความปลอดภัย

การตรวจสอบสิทธิ์โดยใช้หมายเลขโทรศัพท์เพียงอย่างเดียว แม้จะสะดวก แต่ก็มีความปลอดภัยน้อยกว่าวิธีอื่นๆ ที่มีอยู่ เนื่องจากผู้ใช้สามารถโอนสิทธิ์การเป็นเจ้าของหมายเลขโทรศัพท์ระหว่างกันได้ง่าย นอกจากนี้ ในอุปกรณ์ที่มีโปรไฟล์ผู้ใช้หลายโปรไฟล์ ผู้ใช้ที่รับข้อความ SMS ได้จะลงชื่อเข้าใช้บัญชีโดยใช้หมายเลขโทรศัพท์ของอุปกรณ์ได้

หากคุณใช้การลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์ในแอป คุณควรเสนอการลงชื่อเข้าใช้ด้วยวิธีที่ปลอดภัยกว่าควบคู่กันไป และแจ้งให้ผู้ใช้ทราบถึงข้อเสียด้านความปลอดภัยของการใช้การลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์

เปิดใช้การลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์สำหรับโปรเจ็กต์ Firebase

หากต้องการให้ผู้ใช้ลงชื่อเข้าใช้ด้วย SMS คุณต้องเปิดใช้วิธีการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์สำหรับโปรเจ็กต์ Firebase ก่อน โดยทำดังนี้

  1. ในคอนโซล FirebaseFirebase ให้เปิดส่วนการตรวจสอบสิทธิ์
  2. ในหน้าวิธีการลงชื่อเข้าใช้ ให้เปิดใช้วิธีการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์
  3. ในหน้าการตั้งค่า ให้กำหนดนโยบายเกี่ยวกับภูมิภาคที่คุณต้องการ อนุญาตหรือไม่อนุญาตให้ส่งข้อความ SMS สำหรับโปรเจ็กต์ใหม่ นโยบายเริ่มต้นจะไม่อนุญาตภูมิภาคใดเลย

เปิดใช้การตรวจสอบแอป

หากต้องการใช้การตรวจสอบสิทธิ์ด้วยหมายเลขโทรศัพท์ Firebase ต้องสามารถยืนยันได้ว่า คำขอลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์มาจากแอปของคุณ การตรวจสอบสิทธิ์ Firebase ทำได้ 2 วิธีดังนี้ Firebase Authentication

  • การแจ้งเตือน APNs แบบเงียบ: เมื่อคุณลงชื่อเข้าใช้ผู้ใช้ด้วยหมายเลขโทรศัพท์เป็นครั้งแรกในอุปกรณ์ Firebase Authentication จะส่งโทเค็นไปยังอุปกรณ์โดยใช้ข้อความ Push แบบเงียบ หากแอปของคุณ รับการแจ้งเตือนจาก 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 ให้ไปที่ Settings > General จากนั้นคลิกแท็บ Cloud Messaging
    2. ในส่วนคีย์การตรวจสอบสิทธิ์ APNs ในส่วนการกำหนดค่าแอป iOS, ให้คลิกอัปโหลด เพื่ออัปโหลดคีย์การตรวจสอบสิทธิ์สำหรับการพัฒนาหรือ คีย์การตรวจสอบสิทธิ์เวอร์ชันที่ใช้งานจริง หรือทั้ง 2 อย่าง คุณต้องอัปโหลดคีย์อย่างน้อย 1 รายการ
    3. เรียกดูตำแหน่งที่คุณบันทึกคีย์ เลือกคีย์ แล้วคลิก เปิด เพิ่มรหัสคีย์สำหรับคีย์ (มีอยู่ใน Apple Developer Member Center) แล้วคลิก อัปโหลด

    หากมีใบรับรอง APNs อยู่แล้ว คุณสามารถอัปโหลดใบรับรอง แทนได้

  3. ใน Xcode ให้เปิดใช้ความสามารถโหมดเบื้องหลังสำหรับโปรเจ็กต์ แล้วเลือกช่องทำเครื่องหมายสำหรับโหมด**การดึงข้อมูลในเบื้องหลัง** และ**การแจ้งเตือนระยะไกล**

ตั้งค่าการยืนยัน reCAPTCHA

วิธีเปิดใช้ Firebase SDK เพื่อใช้การยืนยัน reCAPTCHA

  1. เพิ่ม URL Scheme ที่กำหนดเองลงในโปรเจ็กต์ Xcode โดยทำดังนี้
    1. เปิดการกำหนดค่าโปรเจ็กต์โดยดับเบิลคลิกชื่อโปรเจ็กต์ใน มุมมองแบบต้นไม้ทางด้านซ้าย เลือกแอปจากส่วน TARGETS แล้ว เลือกแท็บ Info และขยายส่วน URL Types
    2. คลิกปุ่ม + แล้วเพิ่มรหัสแอปที่เข้ารหัสเป็น URL Scheme คุณดูรหัสแอปที่เข้ารหัสได้ในหน้า การตั้งค่าทั่วไปของคอนโซล Firebase ในส่วนสำหรับแอป iOS ปล่อยให้ช่องอื่นๆ ว่างไว้

      เมื่อเสร็จแล้ว การกำหนดค่าควรมีลักษณะคล้ายกับตัวอย่างต่อไปนี้ (แต่มีค่าเฉพาะของแอปพลิเคชัน)

      ภาพหน้าจอของอินเทอร์เฟซการตั้งค่า URL Scheme ที่กำหนดเองของ Xcode
  2. ไม่บังคับ: หากต้องการปรับแต่งวิธีที่แอปแสดง SFSafariViewController เมื่อแสดง reCAPTCHA ให้ผู้ใช้ ให้สร้างคลาสที่กำหนดเอง ซึ่งเป็นไปตามโปรโตคอล AuthUIDelegate แล้วส่งคลาสดังกล่าวไปยัง verifyPhoneNumber(_:uiDelegate:completion:)

ส่งรหัสยืนยันไปยังโทรศัพท์ของผู้ใช้

หากต้องการเริ่มการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์ ให้แสดงอินเทอร์เฟซที่แจ้งให้ผู้ใช้ระบุหมายเลขโทรศัพท์ แล้วเรียก verifyPhoneNumber(_:uiDelegate:completion:) เพื่อขอให้ Firebase ส่งรหัสการตรวจสอบสิทธิ์ไปยังโทรศัพท์ของผู้ใช้ทาง SMS โดยทำดังนี้

  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 ของมุมมอง เมธอด verifyPhoneNumber จะไม่ ส่ง SMS ครั้งที่ 2 เว้นแต่คำขอเดิมจะหมดเวลา

    เมื่อคุณเรียก verifyPhoneNumber(_:uiDelegate:completion:) Firebase จะส่งการแจ้งเตือนแบบพุชแบบเงียบไปยังแอปของคุณ หรือแสดงภาพทดสอบ reCAPTCHA ให้ผู้ใช้ หลังจากที่แอปของคุณได้รับการแจ้งเตือนหรือผู้ใช้ทำภาพทดสอบ reCAPTCHA เสร็จสมบูรณ์ Firebase จะส่งข้อความ SMS ที่มีรหัสการตรวจสอบสิทธิ์ไปยังหมายเลขโทรศัพท์ที่ระบุและส่งรหัสยืนยันไปยังฟังก์ชันการดำเนินการให้เสร็จสมบูรณ์ คุณจะต้องใช้ทั้งรหัสยืนยันและรหัสยืนยัน เพื่อลงชื่อเข้าใช้ผู้ใช้

    นอกจากนี้ คุณยังแปลข้อความ SMS ที่ Firebase ส่งเป็นภาษาท้องถิ่นได้ด้วยการระบุภาษาการตรวจสอบสิทธิ์ผ่านพร็อพเพอร์ตี้ languageCode ในอินสแตนซ์การตรวจสอบสิทธิ์

    Swift

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

    Objective-C

     // Change language code to french.
     [FIRAuth auth].languageCode = @"fr";
  3. บันทึกรหัสยืนยันและกู้คืนรหัสเมื่อแอปโหลด การดำเนินการนี้จะช่วยให้คุณมีรหัสยืนยันที่ถูกต้องอยู่เสมอหากแอปสิ้นสุดลงก่อนที่ผู้ใช้จะทำขั้นตอนการลงชื่อเข้าใช้เสร็จสมบูรณ์ (เช่น ขณะเปลี่ยนไปใช้แอป SMS)

    คุณสามารถเก็บรหัสยืนยันไว้ได้ทุกวิธีที่ต้องการ วิธีง่ายๆ คือการ บันทึกรหัสยืนยันด้วยออบเจ็กต์ 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 Firebase ให้เปิดส่วน การตรวจสอบสิทธิ์
  2. ในแท็บวิธีการลงชื่อเข้าใช้ ให้เปิดใช้ผู้ให้บริการโทรศัพท์หากยังไม่ได้ดำเนินการ
  3. เปิดเมนูแบบ Accordion หมายเลขโทรศัพท์สำหรับการทดสอบ
  4. ระบุหมายเลขโทรศัพท์ที่ต้องการทดสอบ เช่น +1 650-555-3434
  5. ระบุรหัสยืนยัน 6 หลักสำหรับหมายเลขนั้นๆ เช่น 654321
  6. เพิ่ม หมายเลข หากจำเป็น คุณสามารถลบหมายเลขโทรศัพท์และ รหัสได้โดยวางเมาส์เหนือแถวที่เกี่ยวข้องแล้วคลิกไอคอนถังขยะ

การทดสอบด้วยตนเอง

คุณเริ่มใช้หมายเลขโทรศัพท์สมมติในแอปพลิเคชันได้ทันที ซึ่งจะช่วยให้คุณทำการทดสอบด้วยตนเองในระหว่างขั้นตอนการพัฒนาได้โดยไม่พบปัญหาเกี่ยวกับโควต้าหรือการจำกัดอัตรา นอกจากนี้ คุณยังทดสอบได้โดยตรงจากโปรแกรมจำลอง iOS หรือโปรแกรมจำลองของ Android ที่ไม่ได้ติดตั้งบริการ Google Play

เมื่อคุณระบุหมายเลขโทรศัพท์สมมติและส่งรหัสยืนยัน ระบบจะไม่ส่ง SMS จริง แต่คุณต้องระบุรหัสยืนยันที่กำหนดค่าไว้ก่อนหน้านี้เพื่อลงชื่อเข้าใช้ให้เสร็จสมบูรณ์

เมื่อลงชื่อเข้าใช้เสร็จสมบูรณ์ ระบบจะสร้างผู้ใช้ Firebase ที่มีหมายเลขโทรศัพท์ดังกล่าว ผู้ใช้จะมีลักษณะการทำงานและพร็อพเพอร์ตี้เหมือนกับผู้ใช้หมายเลขโทรศัพท์จริง และสามารถเข้าถึง Realtime Database/Cloud Firestore และบริการอื่นๆ ได้ในลักษณะเดียวกัน โทเค็นรหัสที่สร้างขึ้นในระหว่าง กระบวนการนี้มีลายเซ็นเหมือนกับผู้ใช้หมายเลขโทรศัพท์จริง

อีกตัวเลือกหนึ่งคือการตั้งค่าบทบาททดสอบผ่าน การอ้างสิทธิ์ที่กำหนดเองในผู้ใช้เหล่านี้เพื่อแยกความแตกต่างว่าเป็นผู้ใช้ปลอมหากต้องการจำกัด การเข้าถึงเพิ่มเติม

การทดสอบการผสานรวม

นอกจากการทดสอบด้วยตนเองแล้ว Firebase Authentication ยังมี API ที่ช่วยเขียนการทดสอบการผสานรวม สำหรับการทดสอบการตรวจสอบสิทธิ์ด้วยโทรศัพท์ API เหล่านี้จะปิดใช้การตรวจสอบแอปโดยปิดใช้ข้อกำหนด reCAPTCHA ในเว็บและการแจ้งเตือนแบบพุชแบบเงียบใน iOS ซึ่งจะทำให้การทดสอบอัตโนมัติเป็นไปได้ในขั้นตอนเหล่านี้และใช้งานได้ง่ายขึ้น นอกจากนี้ API เหล่านี้ยังช่วยให้คุณทดสอบขั้นตอนการยืนยันทันทีใน Android ได้

ใน iOS คุณต้องตั้งค่า appVerificationDisabledForTesting เป็น TRUE ก่อนที่จะเรียก verifyPhoneNumber ระบบจะประมวลผลการตั้งค่านี้โดยไม่จำเป็นต้องใช้โทเค็น APNs หรือส่งการแจ้งเตือนแบบพุชแบบเงียบในเบื้องหลัง ซึ่งจะช่วยให้ทดสอบในโปรแกรมจำลองได้ง่ายขึ้น นอกจากนี้ การตั้งค่านี้ยังปิดใช้ขั้นตอนการกลับไปใช้ reCAPTCHA

โปรดทราบว่าเมื่อปิดใช้การตรวจสอบแอป การใช้หมายเลขโทรศัพท์ที่ไม่ใช่หมายเลขโทรศัพท์สมมติจะลงชื่อเข้าใช้ไม่สำเร็จ คุณใช้ได้เฉพาะหมายเลขโทรศัพท์สมมติกับ API นี้

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

ภาคผนวก: การใช้การลงชื่อเข้าใช้ด้วยโทรศัพท์โดยไม่ใช้ Swizzling

Firebase Authentication ใช้การแลกเปลี่ยนเมธอดเพื่อรับโทเค็น APNs ของแอปโดยอัตโนมัติ จัดการข้อความ Push แบบเงียบที่ Firebase ส่งไปยังแอป และดักจับการเปลี่ยนเส้นทาง Scheme ที่กำหนดเองจากหน้าการยืนยัน reCAPTCHA ระหว่างการยืนยันโดยอัตโนมัติ

หากไม่ต้องการใช้ Swizzling คุณสามารถปิดใช้ได้โดยเพิ่มแฟล็ก FirebaseAppDelegateProxyEnabled ลงในไฟล์ Info.plist ของแอปและตั้งค่าเป็น NO โปรดทราบว่าการตั้งค่าแฟล็กนี้เป็น NO จะปิดใช้ Swizzling สำหรับผลิตภัณฑ์อื่นๆ ของ Firebase ด้วย ซึ่งรวมถึง Firebase Cloud Messaging

หากปิดใช้ Swizzling คุณต้องส่งโทเค็นอุปกรณ์ APNs, การแจ้งเตือนแบบพุช และ URL การเปลี่ยนเส้นทาง URL Scheme ที่กำหนดเองไปยัง Firebase Authentication อย่างชัดเจน

หากคุณกำลังสร้างแอปพลิเคชัน SwiftUI คุณควรส่งโทเค็นอุปกรณ์ APNs, การแจ้งเตือนแบบพุช และ URL การเปลี่ยนเส้นทาง URL Scheme ที่กำหนดเองไปยัง 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.
}

หากต้องการจัดการการแจ้งเตือนแบบพุช ให้ตรวจสอบการแจ้งเตือนที่เกี่ยวข้องกับการตรวจสอบสิทธิ์ Firebase ในเมธอด application(_:didReceiveRemoteNotification:fetchCompletionHandler:): โดยเรียกเมธอด canHandleNotification(_:) ของ Auth

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 การเปลี่ยนเส้นทาง URL Scheme ที่กำหนดเอง ให้ใช้เมธอด 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 ให้ใช้เมธอด scene(_:openURLContexts:) เพื่อจัดการ URL เปลี่ยนเส้นทาง และส่ง 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;
}

นอกจากนี้ คุณอาจต้องการเพิ่มโค้ดการจัดการข้อผิดพลาดสำหรับข้อผิดพลาดในการตรวจสอบสิทธิ์ทั้งหมด ดูจัดการข้อผิดพลาด