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

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

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

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

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากยังไม่ได้ดำเนินการ
  2. ในไฟล์ Gradle ของโมดูล (ระดับแอป) (โดยปกติจะเป็น <project>/<app-module>/build.gradle.kts หรือ <project>/<app-module>/build.gradle) ให้เพิ่มทรัพยากร Dependency สำหรับคลัง Firebase Authentication สำหรับ Android เราขอแนะนำให้ใช้ Firebase Android BoM เพื่อควบคุมการกำหนดเวอร์ชันของไลบรารี
    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    }

    การใช้ Firebase Android BoM จะทำให้แอปใช้ไลบรารี Firebase Android เวอร์ชันที่เข้ากันได้อยู่เสมอ

    (วิธีอื่น)  เพิ่มไลบรารี Firebase ที่ต้องพึ่งพาโดยไม่ต้องใช้ BoM

    หากเลือกไม่ใช้ Firebase BoM คุณต้องระบุเวอร์ชันของไลบรารี Firebase แต่ละเวอร์ชันในบรรทัดของ Dependency

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

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.1.0")
    }
    หากกำลังมองหาโมดูลไลบรารีสำหรับ Kotlin โดยเฉพาะ ตั้งแต่เดือนตุลาคม 2023 (Firebase BoM 32.5.0) เป็นต้นไป นักพัฒนาซอฟต์แวร์ทั้ง Kotlin และ Java จะใช้โมดูลไลบรารีหลักได้ (ดูรายละเอียดได้ในคําถามที่พบบ่อยเกี่ยวกับโครงการริเริ่มนี้)
  3. หากยังไม่ได้เชื่อมต่อแอปกับโปรเจ็กต์ Firebase ให้เชื่อมต่อจากคอนโซล Firebase
  4. หากคุณยังไม่ได้ตั้งค่าแฮช SHA-1 ของแอปในคอนโซล Firebase ให้ทำดังนี้ ดูข้อมูลเกี่ยวกับการค้นหาแฮช SHA-1 ของแอปได้ที่ การตรวจสอบสิทธิ์ไคลเอ็นต์

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

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

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

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

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

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

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

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

  • Play Integrity API: หากผู้ใช้มีอุปกรณ์ที่ติดตั้ง Google Play services และ Firebase Authentication สามารถยืนยันได้ว่าอุปกรณ์ดังกล่าวถูกต้องด้วย Play Integrity API การลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์จะดำเนินการต่อได้ Firebase Authentication เปิดใช้ Play Integrity API ในโปรเจ็กต์ของ Google ไม่ใช่ในโปรเจ็กต์ของคุณ การดำเนินการนี้จะไม่ส่งผลต่อโควต้า Play Integrity API ในโปรเจ็กต์ของคุณ การสนับสนุน Play Integrity พร้อมให้บริการใน Authentication SDK เวอร์ชัน 21.2.0 ขึ้นไป (Firebase BoM เวอร์ชัน 31.4.0 ขึ้นไป)

    หากต้องการใช้ Play Integrity แต่ยังไม่ได้ระบุลายนิ้วมือ SHA-256 ของแอป ให้ดำเนินการจากการตั้งค่าโปรเจ็กต์ในคอนโซล Firebase โปรดดูรายละเอียดเกี่ยวกับวิธีรับลายนิ้วมือ SHA-256 ของแอปที่หัวข้อการตรวจสอบสิทธิ์ไคลเอ็นต์

  • การยืนยัน reCAPTCHA: ในกรณีที่ใช้ Play Integrity ไม่ได้ เช่น เมื่อผู้ใช้มีอุปกรณ์ที่ไม่มี Google Play servicesติดตั้ง Firebase Authenticationจะใช้การยืนยัน reCAPTCHA เพื่อดำเนินการตามขั้นตอนการลงชื่อเข้าใช้ด้วยโทรศัพท์ให้เสร็จสมบูรณ์ บ่อยครั้งที่ผู้ใช้ไม่ต้องแก้ปัญหาใดๆ ก็สามารถผ่านด่าน reCAPTCHA ได้ โปรดทราบว่าขั้นตอนนี้กำหนดให้ต้องเชื่อมโยง SHA-1 กับแอปพลิเคชัน ขั้นตอนนี้ยังกำหนดให้คีย์ API ของคุณต้องไม่มีข้อจำกัดหรืออยู่ในรายการที่อนุญาตสำหรับ PROJECT_ID.firebaseapp.com ด้วย

    สถานการณ์ที่ reCAPTCHA จะทริกเกอร์

    • หากอุปกรณ์ของผู้ใช้ปลายทางไม่ได้ติดตั้ง Google Play services
    • หากไม่ได้เผยแพร่แอปผ่าน Google Play Store (ใน Authentication SDK เวอร์ชัน 21.2.0 ขึ้นไป)
    • หากโทเค็น SafetyNet ที่ได้รับไม่ถูกต้อง (ใน Authentication SDK เวอร์ชัน < v21.2.0)

    เมื่อใช้ SafetyNet หรือ Play Integrity สำหรับการยืนยันแอป ระบบจะป้อนข้อมูลชื่อแอปที่ระบุจาก Google Play Store ลงในช่อง %APP_NAME% ของเทมเพลต SMS ในสภาวะการณ์ที่ reCAPTCHA ทำงาน %APP_NAME% จะแสดงเป็น PROJECT_ID.firebaseapp.com

คุณสามารถบังคับใช้ขั้นตอนการยืนยัน reCAPTCHA ได้ด้วย forceRecaptchaFlowForTesting คุณปิดใช้การยืนยันแอป (เมื่อใช้หมายเลขโทรศัพท์สมมติ) ได้โดยใช้ setAppVerificationDisabledForTesting

การแก้ปัญหา

  • ข้อผิดพลาด "ไม่มีสถานะเริ่มต้น" เมื่อใช้ reCAPTCHA สำหรับการยืนยันแอป

    กรณีนี้อาจเกิดขึ้นเมื่อขั้นตอน reCAPTCHA เสร็จสมบูรณ์ แต่ไม่ได้เปลี่ยนเส้นทางผู้ใช้กลับไปยังแอปพลิเคชันเนทีฟ หากเกิดกรณีนี้ ระบบจะเปลี่ยนเส้นทางผู้ใช้ไปยัง URL สำรอง PROJECT_ID.firebaseapp.com/__/auth/handler ในเบราว์เซอร์ Firefox ระบบจะปิดใช้การเปิดลิงก์แอปที่มาพร้อมเครื่องโดยค่าเริ่มต้น หากเห็นข้อผิดพลาดข้างต้นใน Firefox ให้ทำตามขั้นตอนในหัวข้อตั้งค่า Firefox สำหรับ Android ให้เปิดลิงก์ในแอปเนทีฟเพื่อเปิดใช้การเปิดลิงก์แอป

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

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

จากนั้นส่งหมายเลขโทรศัพท์ของผู้ใช้ไปยังเมธอด PhoneAuthProvider.verifyPhoneNumber เพื่อขอให้ Firebase ยืนยันหมายเลขโทรศัพท์ของผู้ใช้ เช่น

Kotlin

val options = PhoneAuthOptions.newBuilder(auth)
    .setPhoneNumber(phoneNumber) // Phone number to verify
    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
    .setActivity(this) // Activity (for callback binding)
    .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Java

PhoneAuthOptions options = 
  PhoneAuthOptions.newBuilder(mAuth) 
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // (optional) Activity for callback binding
      // If no activity is passed, reCAPTCHA verification can not be used.
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);     

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

คุณใช้ลักษณะการทํางานนี้เพื่อดําเนินการต่อในกระบวนการลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์ได้หากแอปปิดก่อนที่ผู้ใช้จะลงชื่อเข้าใช้ได้ (เช่น ขณะที่ผู้ใช้ใช้แอป SMS) หลังจากโทรหา verifyPhoneNumber แล้ว ให้ตั้งค่า Flag ที่บ่งบอกว่ากำลังดำเนินการยืนยัน จากนั้นบันทึกการแจ้งว่าไม่เหมาะสมในเมธอด onSaveInstanceState ของกิจกรรม แล้วกู้คืนการแจ้งว่าไม่เหมาะสมใน onRestoreInstanceState สุดท้าย ในonStartของกิจกรรม ให้ตรวจสอบว่ามีการยืนยันไปแล้วหรือยัง หากใช่ ให้โทรหา verifyPhoneNumber อีกครั้ง อย่าลืมล้างการแจ้งเมื่อการยืนยันเสร็จสมบูรณ์หรือไม่สำเร็จ (ดู การเรียกกลับสำหรับการยืนยัน)

หากต้องการจัดการการหมุนหน้าจอและอินสแตนซ์อื่นๆ ของการเริ่มกิจกรรมอีกครั้ง ให้ส่งกิจกรรมของคุณไปยังเมธอด verifyPhoneNumber ระบบจะแยกการเรียกกลับโดยอัตโนมัติเมื่อกิจกรรมหยุดลง คุณจึงเขียนโค้ดการเปลี่ยน UI ในเมธอดการเรียกกลับได้อย่างอิสระ

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

Kotlin

auth.setLanguageCode("fr")
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage()

Java

auth.setLanguageCode("fr");
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage();

เมื่อเรียกใช้ PhoneAuthProvider.verifyPhoneNumber คุณต้องระบุอินสแตนซ์ของ OnVerificationStateChangedCallbacks ด้วย ซึ่งประกอบด้วยการใช้งานฟังก์ชัน Callback ที่จัดการผลลัพธ์ของคําขอ เช่น

Kotlin

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    override fun onVerificationCompleted(credential: PhoneAuthCredential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:$credential")
        signInWithPhoneAuthCredential(credential)
    }

    override fun onVerificationFailed(e: FirebaseException) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e)

        if (e is FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e is FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    override fun onCodeSent(
        verificationId: String,
        token: PhoneAuthProvider.ForceResendingToken,
    ) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:$verificationId")

        // Save verification ID and resending token so we can use them later
        storedVerificationId = verificationId
        resendToken = token
    }
}

Java

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

การติดต่อกลับเพื่อยืนยัน

ในแอปส่วนใหญ่ คุณจะใช้การเรียกกลับ onVerificationCompleted, onVerificationFailed และ onCodeSent คุณอาจใช้ onCodeAutoRetrievalTimeOut ด้วย ทั้งนี้ขึ้นอยู่กับข้อกําหนดของแอป

onVerificationCompleted(PhoneAuthCredential)

ระบบจะเรียกใช้เมธอดนี้ใน 2 สถานการณ์ ได้แก่

  • การยืนยันทันที: ในบางกรณี หมายเลขโทรศัพท์จะได้รับการยืนยันทันทีโดยไม่ต้องส่งหรือป้อนรหัสยืนยัน
  • การดึงข้อมูลอัตโนมัติ: ในอุปกรณ์บางเครื่อง บริการ Google Play สามารถตรวจหา SMS ยืนยันที่เข้ามาโดยอัตโนมัติและทำการยืนยันโดยไม่ต้องให้ผู้ใช้ดำเนินการใดๆ (ความสามารถนี้อาจไม่พร้อมใช้งานกับผู้ให้บริการบางราย) ซึ่งจะใช้ SMS Retriever API ที่มีแฮช 11 อักขระที่ท้ายข้อความ SMS
ไม่ว่าในกรณีใด หมายเลขโทรศัพท์ของผู้ใช้ได้รับการยืนยันเรียบร้อยแล้ว และคุณสามารถใช้ออบเจ็กต์ PhoneAuthCredential ที่ส่งไปยังการเรียกกลับเพื่อลงชื่อเข้าใช้ผู้ใช้

onVerificationFailed(FirebaseException)

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

onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken)

ไม่บังคับ ระบบจะเรียกใช้เมธอดนี้หลังจากที่ส่งรหัสยืนยันทาง SMS ไปยังหมายเลขโทรศัพท์ที่ระบุ

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

onCodeAutoRetrievalTimeOut(String verificationId)

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

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

สร้างออบเจ็กต์ PhoneAuthCredential

หลังจากผู้ใช้ป้อนรหัสยืนยันที่ Firebase ส่งไปยังโทรศัพท์ของผู้ใช้แล้ว ให้สร้างออบเจ็กต์ PhoneAuthCredential โดยใช้รหัสยืนยันและรหัสยืนยันที่ส่งไปยังการเรียกกลับ onCodeSent หรือ onCodeAutoRetrievalTimeOut (เมื่อเรียกใช้ onVerificationCompleted คุณจะได้รับออบเจ็กต์ PhoneAuthCredential โดยตรง คุณจึงข้ามขั้นตอนนี้ได้)

หากต้องการสร้างออบเจ็กต์ PhoneAuthCredential ให้เรียกใช้ PhoneAuthProvider.getCredential ดังนี้

Kotlin

val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

Java

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

ลงชื่อเข้าใช้ผู้ใช้

หลังจากได้รับออบเจ็กต์ PhoneAuthCredential ไม่ว่าจะใน Callback ของ onVerificationCompleted หรือการเรียกใช้ PhoneAuthProvider.getCredential ให้ทำตามขั้นตอนการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์โดยส่งออบเจ็กต์ PhoneAuthCredential ไปยัง FirebaseAuth.signInWithCredential ดังนี้

Kotlin

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    auth.signInWithCredential(credential)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in success, update UI with the signed-in user's information
                Log.d(TAG, "signInWithCredential:success")

                val user = task.result?.user
            } else {
                // Sign in failed, display a message and update the UI
                Log.w(TAG, "signInWithCredential:failure", task.exception)
                if (task.exception is FirebaseAuthInvalidCredentialsException) {
                    // The verification code entered was invalid
                }
                // Update UI
            }
        }
}

Java

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

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

คุณตั้งค่าหมายเลขโทรศัพท์สมมติเพื่อใช้ในการพัฒนาได้ผ่านคอนโซล 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 และบริการอื่นๆ ในลักษณะเดียวกัน โทเค็นระบุตัวตนที่สร้างขึ้นในระหว่างกระบวนการนี้มีลายเซ็นเดียวกับผู้ใช้หมายเลขโทรศัพท์จริง

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

หากต้องการเรียกใช้ขั้นตอนการทดสอบ reCAPTCHA ด้วยตนเอง ให้ใช้เมธอด forceRecaptchaFlowForTesting()

// Force reCAPTCHA flow
FirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();

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

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

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

// Turn off phone auth app verification.
FirebaseAuth.getInstance().getFirebaseAuthSettings()
   .setAppVerificationDisabledForTesting();

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

Java

String phoneNum = "+16505554567";
String testVerificationCode = "123456";

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
FirebaseAuth auth = FirebaseAuth.getInstance();
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                MainActivity.this.enableUserManuallyInputCode();
            }

            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            @Override
            public void onVerificationFailed(@NonNull FirebaseException e) {
                // ...
            }
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

val phoneNum = "+16505554567"
val testVerificationCode = "123456"

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
val options = PhoneAuthOptions.newBuilder(Firebase.auth)
    .setPhoneNumber(phoneNum)
    .setTimeout(30L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        override fun onCodeSent(
            verificationId: String,
            forceResendingToken: PhoneAuthProvider.ForceResendingToken,
        ) {
            // Save the verification id somewhere
            // ...

            // The corresponding whitelisted code above should be used to complete sign-in.
            this@MainActivity.enableUserManuallyInputCode()
        }

        override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
            // Sign in with the credential
            // ...
        }

        override fun onVerificationFailed(e: FirebaseException) {
            // ...
        }
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

นอกจากนี้ คุณยังทดสอบขั้นตอนการดึงข้อมูลอัตโนมัติใน Android ได้โดยการตั้งค่าหมายเลขสมมติและรหัสยืนยันที่เกี่ยวข้องสำหรับการดึงข้อมูลอัตโนมัติโดยการโทรไปที่ setAutoRetrievedSmsCodeForPhoneNumber

เมื่อเรียกใช้ verifyPhoneNumber ระบบจะทริกเกอร์ onVerificationCompleted ด้วย PhoneAuthCredential โดยตรง ซึ่งใช้ได้กับหมายเลขโทรศัพท์สมมติเท่านั้น

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

Java

// The test phone number and code should be whitelisted in the console.
String phoneNumber = "+16505554567";
String smsCode = "123456";

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings();

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode);

PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

// The test phone number and code should be whitelisted in the console.
val phoneNumber = "+16505554567"
val smsCode = "123456"

val firebaseAuth = Firebase.auth
val firebaseAuthSettings = firebaseAuth.firebaseAuthSettings

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode)

val options = PhoneAuthOptions.newBuilder(firebaseAuth)
    .setPhoneNumber(phoneNumber)
    .setTimeout(60L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        override fun onVerificationCompleted(credential: PhoneAuthCredential) {
            // Instant verification is applied and a credential is directly returned.
            // ...
        }

        // ...
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

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

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

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

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

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

หากต้องการออกจากระบบของผู้ใช้ ให้เรียกใช้ signOut โดยทำดังนี้

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();