จัดการข้อผิดพลาดในการยืนยันหมายเลขโทรศัพท์ของ Firebase ใน Android

เมื่อการเรียกใช้ไลบรารี Firebase PNV ล้มเหลว ไลบรารีจะรายงาน FirebasePhoneNumberVerificationException หน้านี้จะแสดงรหัสข้อผิดพลาดทั้งหมดที่ข้อยกเว้นอาจมี เมื่อเกิดข้อผิดพลาดแต่ละรายการ และสิ่งที่แอปควรทำเกี่ยวกับข้อผิดพลาดนั้น

หน้านี้ถือว่าคุณได้ผสานรวม Firebase PNV ตามที่อธิบายไว้ในเริ่มต้นใช้งาน Firebase Phone Number Verification ใน Android แล้ว

วิธีรายงานข้อผิดพลาด

  • เมธอดแบบอะซิงโครนัส (getVerificationSupportInfo(), getVerifiedPhoneNumber() และเมธอดขั้นตอนที่กำหนดเอง) จะแสดงผล Task เมื่อการตรวจสอบล้มเหลว Task จะล้มเหลวพร้อมกับ FirebasePhoneNumberVerificationException ซึ่งคุณจะได้รับใน addOnFailureListener

  • enableTestSession() เป็นแบบซิงโครนัส โดยจะปาFirebasePhoneNumberVerificationExceptionใส่โดยตรง

อ่าน errorCode ของข้อยกเว้นเพื่อดูว่าเกิดข้อผิดพลาดใดขึ้น รหัส Firebase PNV เป็นค่าคงที่ในคลาส FirebasePnvStatusCodes หากความล้มเหลวมาจากบริการ Google Play errorCode อาจเป็นค่า CommonStatusCodes เช่น NETWORK_ERROR ได้ด้วย

อุปกรณ์หรือซิมที่ไม่รองรับไม่ใช่ข้อผิดพลาด getVerificationSupportInfo() สำเร็จและรายงาน isSupported() เป็น false สำหรับซิมนั้น และ getReason() จะบอกเหตุผลให้คุณทราบ ดูอุปกรณ์และซิมที่ไม่รองรับ

รหัสข้อผิดพลาด

การตั้งค่าเซสชันการทดสอบ

ข้อผิดพลาดเหล่านี้จะแสดงพร้อมกันโดย enableTestSession()

รหัสข้อผิดพลาด สาเหตุ การดำเนินการที่แนะนำ
TEST_SESSION_ALREADY_ENABLED
(55508)
มีการเรียก enableTestSession() มากกว่า 1 ครั้งในกระบวนการเดียวกันของแอป FirebasePhoneNumberVerification.getInstance() จะแสดงผลอินสแตนซ์เดียวกันทุกครั้ง ดังนั้นจึงเกิดขึ้นเมื่อมีการสร้าง Activity ที่เรียกใช้ขึ้นมาใหม่ด้วย เรียกใช้ enableTestSession() 1 ครั้งต่อกระบวนการ เช่น ใน Application.onCreate() ดูหัวข้อเริ่มต้นไลบรารีในโหมดทดสอบ
INVALID_TEST_NUMBER_ID
(55507)
โทเค็นทดสอบที่ส่งไปยัง enableTestSession() ว่างเปล่า ตรวจสอบว่าบิลด์ของคุณส่งโทเค็นที่คุณสร้างในคอนโซล Firebase และเรียกใช้ enableTestSession() เฉพาะเมื่อโทเค็นไม่ว่างเปล่า

การยืนยัน

ข้อผิดพลาดเหล่านี้ทำให้ Task ที่ getVerifiedPhoneNumber() แสดงผลไม่สำเร็จ

รหัสข้อผิดพลาด สาเหตุ การดำเนินการที่แนะนำ
CREDENTIAL_MANAGER_ERROR
(55506)
Android Credential Manager ไม่แสดงหมายเลขโทรศัพท์ หาก cause ของข้อยกเว้นเป็น GetCredentialCancellationException แสดงว่าผู้ใช้น่าจะปิดหน้าจอขอความยินยอมไป เสนอวิธีอื่นในการยืนยันหมายเลขโทรศัพท์ เช่น SMS อย่าลองอีกครั้งโดยอัตโนมัติ เนื่องจากผู้ใช้จะเห็นหน้าจอขอความยินยอมอีกครั้ง
CARRIER_NOT_SUPPORTED
(55501)
ระบบไม่รองรับผู้ให้บริการของซิมที่เลือก หรืออุปกรณ์ไม่มีข้อมูลการสมัครใช้บริการที่จำเป็นสำหรับการยืนยัน เปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS
UNSUPPORTED_OPERATION
(55505)
Firebase PNV ไม่พร้อมให้บริการสำหรับคำขอนี้ในอุปกรณ์ เปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS
PREFLIGHT_CHECK_FAILED
(55504)
แบ็กเอนด์ Firebase PNV ไม่สามารถสร้างคำขอการยืนยันก่อนที่จะแสดงหน้าจอขอความยินยอม เปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS หากเกิดข้อผิดพลาดนี้กับทุกคำขอ ให้ตรวจสอบว่าได้ตั้งค่าแอปอย่างถูกต้อง (ดูหัวข้ออัปเกรดเป็นโหมดโปรดักชัน)
INTEGRITY_CHECK_FAILED
(55503)
อุปกรณ์หรือแอปไม่ผ่านการตรวจสอบความสมบูรณ์ เปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS
INVALID_DIGITAL_CREDENTIAL_RESPONSE
(55502)
อ่านการตอบกลับจาก Credential Manager ไม่ได้ หรือแลกเปลี่ยนเป็นหมายเลขโทรศัพท์ที่ยืนยันแล้วไม่ได้ เปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS
INVALID_TEST_NUMBER_ID
(55507)
ในโหมดทดสอบ แบ็กเอนด์ Firebase PNV ปฏิเสธโทเค็นทดสอบ เช่น เนื่องจากโทเค็นหมดอายุ โทเค็นทดสอบมี TTL 7 วัน โทเค็นทดสอบที่ถูกปฏิเสธมักจะรายงานรหัสนี้ หากคุณเห็นข้อผิดพลาดอื่นๆ ในโหมดทดสอบ ให้ตรวจสอบด้วยว่าโทเค็นเป็นปัจจุบัน สร้างโทเค็นทดสอบใหม่ในคอนโซล Firebase และสร้างแอปใหม่
ACTIVITY_CONTEXT_REQUIRED
(55509)
Context ที่ส่งไปยัง getVerifiedPhoneNumber() ไม่ใช่ Activity เมธอดต้องมี Activity เพื่อแสดงหน้าจอขอความยินยอม ผ่าน Activity ปัจจุบัน ซึ่งเป็นข้อบกพร่องในแอป ไม่ใช่เงื่อนไขที่ต้องจัดการขณะรันไทม์

การตรวจสอบการสนับสนุน

Task ที่แสดงผลโดย getVerificationSupportInfo() จะไม่สำเร็จก็ต่อเมื่อการตรวจสอบไม่สามารถทำงานได้ ในกรณีนี้ errorCode จะเป็นค่า CommonStatusCodes ของบริการ Google Play หรือ CARRIER_NOT_SUPPORTED ถือว่าอุปกรณ์ไม่รองรับและเปลี่ยนไปใช้วิธีการยืนยันอื่น เช่น SMS

ขณะที่เปิดใช้เซสชันการทดสอบ getVerificationSupportInfo() จะไม่ติดต่อแบ็กเอนด์ Firebase PNV และจะรายงานซิมทดสอบว่ารองรับเสมอ แม้ว่าโทเค็นทดสอบจะหมดอายุแล้วก็ตาม

โฟลว์ที่กำหนดเอง

หากคุณใช้ขั้นตอนที่กำหนดเองแทนgetVerifiedPhoneNumber() ให้ทำดังนี้

  • getDigitalCredentialPayload() ดำเนินการไม่สำเร็จโดยมีข้อผิดพลาด PREFLIGHT_CHECK_FAILED หรือ INVALID_TEST_NUMBER_ID หากแบ็กเอนด์ปฏิเสธโทเค็นทดสอบ
  • exchangeCredentialResponseForPhoneNumber() ล้มเหลวพร้อมข้อความ INVALID_DIGITAL_CREDENTIAL_RESPONSE หรือ INVALID_TEST_NUMBER_ID หากแบ็กเอนด์ปฏิเสธโทเค็นทดสอบ
  • การเรียกใช้ Credential Manager ของคุณเองจะแสดง GetCredentialException ซึ่งคุณจะจัดการโดยตรง

อุปกรณ์และซิมที่ไม่รองรับ

เมื่อ isSupported() เป็น false สำหรับซิม getReason() จะแสดงผลค่า VerificationSupportStatus ค่าใดค่าหนึ่งต่อไปนี้

ค่า ความหมาย
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED ระบบไม่รองรับผู้ให้บริการของซิม ดูผู้ให้บริการที่รองรับ
INCAPABLE_DUE_TO_ANDROID_VERSION อุปกรณ์ใช้ Android เวอร์ชันที่เก่ากว่า Android 9 (ระดับ API 28)
INCAPABLE_DUE_TO_SIM_STATE ซิมไม่พร้อมใช้งาน ซิมที่ล็อกอยู่หรือยังโหลดอยู่ก็อาจรายงาน INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED ได้เช่นกัน เนื่องจากระบบจะตรวจสอบผู้ให้บริการก่อน

ในแต่ละกรณี ให้ใช้วิธีการยืนยันอื่น เช่น SMS สำหรับซิมนั้น

ตัวอย่าง

ตัวอย่างต่อไปนี้จะจัดการข้อผิดพลาดที่แอปทั่วไปต้องแยกแยะเมื่อเรียกใช้ getVerifiedPhoneNumber()

Kotlin

import android.util.Log
// Credential Manager is included with the Firebase PNV library.
import androidx.credentials.exceptions.GetCredentialCancellationException
import com.google.firebase.pnv.FirebasePhoneNumberVerification
import com.google.firebase.pnv.FirebasePhoneNumberVerificationException
import com.google.firebase.pnv.FirebasePnvStatusCodes

private const val TAG = "PhoneVerification"

// In your Activity:
private fun verifyPhoneNumber() {
    FirebasePhoneNumberVerification.getInstance()
        .getVerifiedPhoneNumber(this)
        .addOnSuccessListener { result ->
            // Send result.getToken() to your backend.
        }
        .addOnFailureListener { e -> handleFpnvError(e) }
}

private fun handleFpnvError(e: Exception) {
    if (e !is FirebasePhoneNumberVerificationException) {
        Log.w(TAG, "Firebase PNV failed", e)
        showSmsVerification()
        return
    }
    when (e.errorCode) {
        FirebasePnvStatusCodes.CREDENTIAL_MANAGER_ERROR -> {
            if (e.cause is GetCredentialCancellationException) {
                // The user dismissed the consent screen.
            }
            showSmsVerification()
        }
        FirebasePnvStatusCodes.INVALID_TEST_NUMBER_ID -> {
            // Test mode only: generate a new test token.
            Log.e(TAG, "Firebase PNV test token rejected", e)
        }
        FirebasePnvStatusCodes.ACTIVITY_CONTEXT_REQUIRED -> {
            // App bug: pass an Activity to getVerifiedPhoneNumber().
            Log.e(TAG, "Firebase PNV needs an Activity context", e)
        }
        else -> {
            // Carrier not supported, network errors, and other failures.
            Log.w(TAG, "Firebase PNV failed with error code ${e.errorCode}", e)
            showSmsVerification()
        }
    }
}

ในตัวอย่างนี้ showSmsVerification() คือขั้นตอนการยืนยันหมายเลขโทรศัพท์ที่มีอยู่ของแอป

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