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

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

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

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

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

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

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

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

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

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

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

  1. ในคอนโซล Firebase ให้เปิดส่วนการตรวจสอบสิทธิ์
  2. ในหน้าวิธีการลงชื่อเข้าใช้ ให้เปิดใช้วิธีการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์

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

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

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

    สําหรับ iOS 8.0 ขึ้นไป การแจ้งเตือนแบบเงียบไม่จําเป็นต้องได้รับความยินยอมจากผู้ใช้อย่างชัดเจน จึงจะไม่ได้รับผลกระทบจากการที่ผู้ใช้ปฏิเสธที่จะรับการแจ้งเตือน APNs ในแอป ดังนั้นแอปจึงไม่ต้องขอสิทธิ์จากผู้ใช้เพื่อรับการแจ้งเตือนแบบ Push เมื่อใช้การตรวจสอบสิทธิ์หมายเลขโทรศัพท์ของ Firebase

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

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

เริ่มรับการแจ้งเตือนแบบปิดเสียง

วิธีเปิดใช้การแจ้งเตือน APNs เพื่อใช้กับ Firebase Authentication

  1. ใน Xcode ให้ เปิดใช้ข้อความ Push สําหรับโปรเจ็กต์
  2. อัปโหลดคีย์การตรวจสอบสิทธิ์ APNs ไปยัง Firebase หากยังไม่มีคีย์การตรวจสอบสิทธิ์ APNs โปรดสร้างคีย์ในศูนย์สมาชิกนักพัฒนาแอปของ Apple

    1. ในโปรเจ็กต์ในคอนโซล Firebase ให้เลือกไอคอนรูปเฟือง เลือกการตั้งค่าโปรเจ็กต์ แล้วเลือกแท็บการรับส่งข้อความระบบคลาวด์

    2. ในส่วนคีย์การตรวจสอบสิทธิ์ APNs ใต้การกำหนดค่าแอป iOS ให้คลิกปุ่มอัปโหลด

    3. เรียกดูตำแหน่งที่คุณบันทึกคีย์ไว้ เลือกคีย์ แล้วคลิกเปิด เพิ่มรหัสคีย์สำหรับคีย์ (ดูได้ใน ศูนย์สมาชิกนักพัฒนาแอปของ Apple) แล้วคลิกอัปโหลด

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

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

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

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

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

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

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

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

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

  1. รับหมายเลขโทรศัพท์ของผู้ใช้

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

  2. โทรหา verifyPhoneNumber(_:uiDelegate:completion:) โดยส่งหมายเลขโทรศัพท์ของผู้ใช้
    SwiftObjective-C
    PhoneAuthProvider.provider()
      .verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
          if let error = error {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // Sign in using the verificationID and the code sent to the user
          // ...
      }
    [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput
                                            UIDelegate:nil
                                            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
      if (error) {
        [self showMessagePrompt:error.localizedDescription];
        return;
      }
      // Sign in using the verificationID and the code sent to the user
      // ...
    }];

    เมธอด verifyPhoneNumber เป็นแบบเข้าซ้ำได้: หากคุณเรียกใช้หลายครั้ง เช่น ในเมธอด onAppear ของมุมมอง เมธอด verifyPhoneNumber จะไม่ส่ง SMS รายการที่ 2 เว้นแต่คำขอเดิมจะหมดเวลา

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

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

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

    คุณเก็บรหัสยืนยันไว้ได้ไม่ว่าจะด้วยวิธีใดก็ตาม วิธีง่ายๆ คือบันทึกรหัสการยืนยันด้วยออบเจ็กต์ NSUserDefaults โดยทำดังนี้

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

    จากนั้นคุณจึงกู้คืนค่าที่บันทึกไว้ได้ โดยทำดังนี้

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

หากการเรียกใช้ verifyPhoneNumber(_:uiDelegate:completion:) สำเร็จ คุณสามารถแจ้งให้ผู้ใช้พิมพ์รหัสยืนยันเมื่อได้รับรหัสดังกล่าวในข้อความ SMS

ลงชื่อเข้าใช้ผู้ใช้ด้วยรหัสยืนยัน

หลังจากผู้ใช้ระบุรหัสยืนยันจากข้อความ SMS ในแอปของคุณแล้ว ให้ลงชื่อเข้าใช้ผู้ใช้โดยสร้างออบเจ็กต์ FIRPhoneAuthCredential จากรหัสยืนยันและรหัสยืนยัน แล้วส่งออบเจ็กต์นั้นให้กับ signInWithCredential:completion:

  1. รับรหัสยืนยันจากผู้ใช้
  2. สร้างออบเจ็กต์ FIRPhoneAuthCredential จากรหัสยืนยันและรหัสยืนยัน
    SwiftObjective-C
    let credential = PhoneAuthProvider.provider().credential(
      withVerificationID: verificationID,
      verificationCode: verificationCode
    )
    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. ลงชื่อเข้าใช้ผู้ใช้ด้วยออบเจ็กต์ FIRPhoneAuthCredential
    SwiftObjective-C
    Auth.auth().signIn(with: credential) { authResult, error in
        if let error = error {
          let authError = error as NSError
          if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue {
            // The user is a multi-factor user. Second factor challenge is required.
            let resolver = authError
              .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
            var displayNameString = ""
            for tmpFactorInfo in resolver.hints {
              displayNameString += tmpFactorInfo.displayName ?? ""
              displayNameString += " "
            }
            self.showTextInputPrompt(
              withMessage: "Select factor to sign in\n\(displayNameString)",
              completionBlock: { userPressedOK, displayName in
                var selectedHint: PhoneMultiFactorInfo?
                for tmpFactorInfo in resolver.hints {
                  if displayName == tmpFactorInfo.displayName {
                    selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo
                  }
                }
                PhoneAuthProvider.provider()
                  .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil,
                                     multiFactorSession: resolver
                                       .session) { verificationID, error in
                    if error != nil {
                      print(
                        "Multi factor start sign in failed. Error: \(error.debugDescription)"
                      )
                    } else {
                      self.showTextInputPrompt(
                        withMessage: "Verification code for \(selectedHint?.displayName ?? "")",
                        completionBlock: { userPressedOK, verificationCode in
                          let credential: PhoneAuthCredential? = PhoneAuthProvider.provider()
                            .credential(withVerificationID: verificationID!,
                                        verificationCode: verificationCode!)
                          let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator
                            .assertion(with: credential!)
                          resolver.resolveSignIn(with: assertion!) { authResult, error in
                            if error != nil {
                              print(
                                "Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
                              )
                            } else {
                              self.navigationController?.popViewController(animated: true)
                            }
                          }
                        }
                      )
                    }
                  }
              }
            )
          } else {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // ...
          return
        }
        // User is signed in
        // ...
    }
    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult,
                                           NSError * _Nullable error) {
        if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
          FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
          NSMutableString *displayNameString = [NSMutableString string];
          for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
            [displayNameString appendString:tmpFactorInfo.displayName];
            [displayNameString appendString:@" "];
          }
          [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                               completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
           FIRPhoneMultiFactorInfo* selectedHint;
           for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
             if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
               selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
             }
           }
           [FIRPhoneAuthProvider.provider
            verifyPhoneNumberWithMultiFactorInfo:selectedHint
            UIDelegate:nil
            multiFactorSession:resolver.session
            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
              if (error) {
                [self showMessagePrompt:error.localizedDescription];
              } else {
                [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                     completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
                 FIRPhoneAuthCredential *credential =
                     [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                                  verificationCode:verificationCode];
                 FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
                 [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
                   if (error) {
                     [self showMessagePrompt:error.localizedDescription];
                   } else {
                     NSLog(@"Multi factor finanlize sign in succeeded.");
                   }
                 }];
               }];
              }
            }];
         }];
        }
      else if (error) {
        // ...
        return;
      }
      // User successfully signed in. Get user data from the FIRUser object
      if (authResult == nil) { return; }
      FIRUser *user = authResult.user;
      // ...
    }];

ทดสอบด้วยหมายเลขโทรศัพท์สมมติ

คุณตั้งค่าหมายเลขโทรศัพท์สมมติเพื่อใช้ในการพัฒนาได้ผ่านคอนโซล Firebase การทดสอบด้วยหมายเลขโทรศัพท์สมมติมีประโยชน์ดังนี้

  • ทดสอบการตรวจสอบสิทธิ์หมายเลขโทรศัพท์โดยไม่ใช้โควต้าการใช้งาน
  • ทดสอบการตรวจสอบหมายเลขโทรศัพท์โดยไม่ต้องส่งข้อความ SMS จริง
  • ทำการทดสอบติดต่อกันโดยใช้หมายเลขโทรศัพท์เดียวกันโดยไม่ถูกจํากัด วิธีนี้ช่วยลดความเสี่ยงที่จะถูกปฏิเสธในระหว่างกระบวนการตรวจสอบของ 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 ยังมี API ที่ช่วยเขียนการทดสอบการผสานรวมสำหรับการทดสอบการตรวจสอบสิทธิ์ทางโทรศัพท์ API เหล่านี้จะปิดใช้การยืนยันแอปโดยปิดใช้ข้อกําหนด reCAPTCHA ในเว็บและการแจ้งเตือน Push แบบเงียบใน iOS ซึ่งทำให้การทดสอบอัตโนมัติในขั้นตอนเหล่านี้เป็นไปได้และใช้งานได้ง่ายขึ้น นอกจากนี้ ยังช่วยให้สามารถทดสอบขั้นตอนการยืนยันทันทีใน Android

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

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

SwiftObjective-C
let phoneNumber = "+16505554567"

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

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

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

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

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

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

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

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

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

หากต้องการรับโทเค็นอุปกรณ์ APN ให้ใช้วิธี application(_:didRegisterForRemoteNotificationsWithDeviceToken:) แล้วส่งโทเค็นอุปกรณ์ไปยังเมธอด setAPNSToken(_:type:) ของ Auth

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

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

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

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

หากต้องการจัดการ URL เปลี่ยนเส้นทางรูปแบบที่กำหนดเอง ให้ใช้เมธอด application(_:open:options:) และส่ง URL ไปยังเมธอด canHandleURL(_:) ของ Auth

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

หากคุณใช้ SwiftUI หรือ UISceneDelegate ให้ใช้เมธอด scene(_:openURLContexts:) เพื่อจัดการ URL เปลี่ยนเส้นทาง และส่ง URL ไปยังเมธอด canHandleURL(_:) ของ Auth

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

ขั้นตอนถัดไป

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

  • ในแอป คุณสามารถดูข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากออบเจ็กต์ User โปรดดูหัวข้อจัดการผู้ใช้

  • ใน Firebase Realtime Database และ Cloud Storage กฎความปลอดภัย คุณสามารถรับรหัสผู้ใช้ที่ไม่ซ้ำของผู้ใช้ที่ลงชื่อเข้าใช้จากตัวแปร auth และนำไปใช้ควบคุมข้อมูลที่ผู้ใช้เข้าถึงได้

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

หากต้องการออกจากระบบของผู้ใช้ ให้โทร signOut:

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

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