หากรองรับการลงชื่อเข้าใช้ด้วยบัญชี Google คุณสามารถใช้ไคลเอ็นต์การลงชื่อเข้าใช้แบบแตะครั้งเดียวเพื่อให้ผู้ใช้ได้รับประสบการณ์การสร้างบัญชีที่ราบรื่นซึ่งไม่นำผู้ใช้ออกจากบริบทของแอป
เมื่อคุณแสดง UI แบบ One Tap ระบบจะแจ้งให้ผู้ใช้สร้างบัญชีใหม่ในแอปโดยใช้บัญชี Google บัญชีใดบัญชีหนึ่งในอุปกรณ์ หากผู้ใช้เลือกที่จะดำเนินการต่อ คุณจะได้รับโทเค็นระบุตัวตนที่มีข้อมูลโปรไฟล์พื้นฐาน ได้แก่ ชื่อ รูปโปรไฟล์ และอีเมลที่ยืนยันแล้ว ซึ่งคุณใช้สร้างบัญชีใหม่ได้
การใช้การสร้างบัญชีแบบ One Tap แบ่งออกเป็น 2 ส่วน ดังนี้
- การผสานรวมไคลเอ็นต์ One Tap เข้ากับแอป ซึ่งอธิบายไว้ในหน้านี้ การดำเนินการนี้ส่วนใหญ่เหมือนกับการใช้ฟีเจอร์ลงชื่อเข้าใช้ด้วย One Tap แต่มีการกําหนดค่าที่แตกต่างกันเล็กน้อย
- เพิ่มความสามารถในการสร้างบัญชีผู้ใช้จากโทเค็น Google ID ลงในแบ็กเอนด์ ซึ่งจะกล่าวถึงในการใช้โทเค็นระบุตัวตนในแบ็กเอนด์
ฉันควรใช้การลงชื่อสมัครใช้ด้วย One Tap ที่ไหน
ตําแหน่งที่จะเสนอการลงชื่อสมัครใช้ด้วย One Tap ให้แก่ผู้ใช้ได้อย่างมีประสิทธิภาพมากที่สุดคือบริบทที่การลงชื่อเข้าใช้จะเปิดใช้ฟีเจอร์ใหม่ๆ ก่อนอื่น ให้ลองลงชื่อเข้าใช้ผู้ใช้ด้วยข้อมูลเข้าสู่ระบบที่บันทึกไว้ หากไม่พบข้อมูลเข้าสู่ระบบที่บันทึกไว้ ให้เสนอสร้างบัญชีใหม่ให้ผู้ใช้
ก่อนเริ่มต้น
ตั้งค่าโปรเจ็กต์คอนโซล Google API และโปรเจ็กต์ Android ตามที่อธิบายไว้ในเริ่มต้นใช้งานฟีเจอร์ลงชื่อเข้าใช้แบบแตะครั้งเดียว
1. กำหนดค่าไคลเอ็นต์ One Tap
หากต้องการกำหนดค่าไคลเอ็นต์ One Tap สำหรับการสร้างบัญชี ให้ทำดังนี้
- อย่าเปิดใช้คำขอข้อมูลเข้าสู่ระบบด้วยรหัสผ่าน (การลงชื่อสมัครใช้ด้วย One Tap ใช้ได้กับการตรวจสอบสิทธิ์แบบใช้โทเค็นเท่านั้น)
เปิดใช้คําขอโทเค็นระบุตัวตนของ Google โดยใช้
setGoogleIdTokenRequestOptions()
และการตั้งค่าต่อไปนี้- ตั้งค่ารหัสไคลเอ็นต์เซิร์ฟเวอร์เป็นรหัสที่คุณสร้างในคอนโซล Google API โปรดทราบว่านี่คือรหัสไคลเอ็นต์ของเซิร์ฟเวอร์ ไม่ใช่รหัสไคลเอ็นต์ Android
- กำหนดค่าไคลเอ็นต์ให้แสดงบัญชี Google ทั้งหมดในอุปกรณ์ กล่าวคือ ไม่กรองตามบัญชีที่ได้รับอนุญาต
- นอกจากนี้ คุณยังขอหมายเลขโทรศัพท์ที่ยืนยันแล้วสำหรับบัญชีได้อีกด้วย
Java
public class YourActivity extends AppCompatActivity { // ... private SignInClient oneTapClient; private BeginSignInRequest signUpRequest; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); oneTapClient = Identity.getSignInClient(this); signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build(); // ... } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private lateinit var oneTapClient: SignInClient private lateinit var signUpRequest: BeginSignInRequest override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) oneTapClient = Identity.getSignInClient(this) signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build() // ... } // ... }
2. ติดตามการยกเลิก UI ของ One Tap
คุณควรติดตามว่าผู้ใช้ปฏิเสธที่จะใช้ฟีเจอร์ลงชื่อสมัครใช้แบบ One Tap ไปแล้วหรือไม่โดยการปิดข้อความแจ้งหรือแตะนอกข้อความแจ้ง ซึ่งอาจง่ายเพียงพร็อพเพอร์ตี้บูลีนของกิจกรรม (ดูหยุดแสดง UI การแตะเพียงครั้งเดียวด้านล่าง)
3. แสดง UI การลงชื่อสมัครใช้ด้วย One Tap
หากผู้ใช้ไม่ได้ปฏิเสธที่จะใช้ One Tap เพื่อสร้างบัญชีใหม่ ให้เรียกใช้เมธอด beginSignIn()
ของออบเจ็กต์ไคลเอ็นต์ และแนบ Listeners กับ Task
ที่แสดงผล โดยปกติแล้ว แอปจะทำขั้นตอนนี้เมื่อคําขอลงชื่อเข้าใช้แบบแตะครั้งเดียวไม่พบข้อมูลเข้าสู่ระบบที่บันทึกไว้ ซึ่งก็คือในโปรแกรมรับฟังการดําเนินการที่ไม่สําเร็จของคําขอลงชื่อเข้าใช้
ไคลเอ็นต์ One Tap จะเรียกฟังก์ชันการฟังผลลัพธ์สำเร็จหากผู้ใช้ตั้งค่าบัญชี Google ไว้อย่างน้อย 1 บัญชีในอุปกรณ์ ใน Listener ที่ดำเนินการสำเร็จ ให้รับ Intent ที่รอดำเนินการจากผลลัพธ์ Task
แล้วส่งไปยัง startIntentSenderForResult()
เพื่อเริ่ม UI การแตะครั้งเดียว
หากผู้ใช้ไม่มีบัญชี Google ในอุปกรณ์ ไคลเอ็นต์ One Tap จะเรียกฟังก์ชันการฟังการไม่สําเร็จ ในกรณีนี้ คุณไม่จำเป็นต้องดำเนินการใดๆ เพียงแค่แสดงประสบการณ์การใช้งานของแอปที่ออกจากระบบต่อไป และผู้ใช้จะลงชื่อสมัครใช้ตามขั้นตอนการสร้างบัญชีปกติได้
Java
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {
try {
startIntentSenderForResult(
result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
Kotlin
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this) { result ->
try {
startIntentSenderForResult(
result.pendingIntent.intentSender, REQ_ONE_TAP,
null, 0, 0, 0)
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
}
}
.addOnFailureListener(this) { e ->
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.localizedMessage)
}
4. จัดการคําตอบของผู้ใช้
ระบบจะรายงานการตอบสนองของผู้ใช้ต่อข้อความแจ้งให้ลงชื่อสมัครใช้แบบ One Tap ไปยังแอปของคุณโดยใช้เมธอด onActivityResult()
ของกิจกรรม หากผู้ใช้เลือกสร้างบัญชี ผลลัพธ์จะเป็นโทเค็น Google ID หากผู้ใช้ปฏิเสธที่จะลงชื่อสมัครใช้ ไม่ว่าจะโดยการปิด UI การชำระเงินแบบไม่ต้องสัมผัสหรือแตะนอก UI ดังกล่าว ระบบจะแสดงผลลัพธ์พร้อมรหัส RESULT_CANCELED
แอปของคุณต้องจัดการกับทั้ง 2 กรณี
สร้างบัญชีด้วยโทเค็น Google ID
หากผู้ใช้เลือกลงชื่อสมัครใช้ด้วยบัญชี Google คุณจะได้รับโทเค็นระบุตัวตนสำหรับผู้ใช้โดยการส่งข้อมูล Intent จาก onActivityResult()
ไปยังเมธอด getSignInCredentialFromIntent()
ของไคลเอ็นต์ One Tap ข้อมูลเข้าสู่ระบบจะมีพร็อพเพอร์ตี้ googleIdToken
ที่ไม่ใช่ค่าว่าง
ใช้โทเค็นระบุตัวตนเพื่อสร้างบัญชีในแบ็กเอนด์ (ดูตรวจสอบสิทธิ์กับแบ็กเอนด์โดยใช้โทเค็นระบุตัวตน) และลงชื่อเข้าใช้ผู้ใช้
ข้อมูลเข้าสู่ระบบยังมีรายละเอียดเพิ่มเติมที่คุณขอด้วย เช่น หมายเลขโทรศัพท์ที่ยืนยันแล้วของบัญชี (หากมี)
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data); String idToken = credential.getGoogleIdToken(); if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token."); } } catch (ApiException e) { // ... } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { val credential = oneTapClient.getSignInCredentialFromIntent(data) val idToken = credential.googleIdToken when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token.") } else -> { // Shouldn't happen. Log.d(TAG, "No ID token!") } } } catch (e: ApiException) { // ... } } } // ... }
หยุดแสดง UI ของ One Tap
หากผู้ใช้ปฏิเสธที่จะลงชื่อเข้าใช้ การเรียกใช้ getSignInCredentialFromIntent()
จะแสดง ApiException
พร้อมรหัสสถานะ CommonStatusCodes.CANCELED
เมื่อเกิดกรณีนี้ คุณควรหยุดแสดง UI การลงชื่อเข้าใช้แบบแตะครั้งเดียวชั่วคราวเพื่อไม่ให้ผู้ใช้รำคาญกับข้อความแจ้งซ้ำๆ ตัวอย่างต่อไปนี้จะทําเช่นนี้โดยการตั้งค่าพร็อพเพอร์ตี้ในกิจกรรม ซึ่งระบบจะใช้เพื่อพิจารณาว่าจะเสนอฟีเจอร์ลงชื่อเข้าใช้แบบแตะครั้งเดียวให้ผู้ใช้หรือไม่ อย่างไรก็ตาม คุณยังบันทึกค่าลงใน SharedPreferences
หรือใช้วิธีอื่นๆ ก็ได้
คุณควรจำกัดอัตราการแสดงข้อความแจ้งให้ลงชื่อเข้าใช้ด้วย One Tap ของคุณเอง หากไม่ตั้งค่านี้และผู้ใช้ยกเลิกข้อความแจ้งหลายรายการติดต่อกัน โปรแกรมรับส่งอีเมลแบบแตะครั้งเดียวจะไม่แสดงข้อความแจ้งต่อผู้ใช้เป็นเวลา 24 ชั่วโมง
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { // ... } catch (ApiException e) { switch (e.getStatusCode()) { case CommonStatusCodes.CANCELED: Log.d(TAG, "One-tap dialog was closed."); // Don't re-prompt the user. showOneTapUI = false; break; case CommonStatusCodes.NETWORK_ERROR: Log.d(TAG, "One-tap encountered a network error."); // Try again or just ignore. break; default: Log.d(TAG, "Couldn't get credential from result." + e.getLocalizedMessage()); break; } } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { // ... } catch (e: ApiException) { when (e.statusCode) { CommonStatusCodes.CANCELED -> { Log.d(TAG, "One-tap dialog was closed.") // Don't re-prompt the user. showOneTapUI = false } CommonStatusCodes.NETWORK_ERROR -> { Log.d(TAG, "One-tap encountered a network error.") // Try again or just ignore. } else -> { Log.d(TAG, "Couldn't get credential from result." + " (${e.localizedMessage})") } } } } } } // ... }
ขั้นตอนถัดไป
เมื่อผู้ใช้ลงชื่อสมัครใช้แบบ One Tap จนเสร็จสมบูรณ์ คุณจะได้รับโทเค็น Google ID ซึ่งประกอบด้วยข้อมูลโปรไฟล์พื้นฐานบางอย่าง เช่น อีเมล ชื่อเต็ม และ URL รูปโปรไฟล์ของผู้ใช้ สําหรับแอปจํานวนมาก ข้อมูลนี้เพียงพอที่จะให้คุณตรวจสอบสิทธิ์ผู้ใช้ในแบ็กเอนด์และสร้างบัญชีใหม่
หากต้องการข้อมูลเพิ่มเติมเพื่อสร้างบัญชีให้เสร็จสมบูรณ์ เช่น วันเกิดของผู้ใช้ ให้แสดงขั้นตอนการลงชื่อสมัครใช้แบบละเอียดแก่ผู้ใช้เพื่อขอข้อมูลเพิ่มเติม จากนั้นส่งข้อมูลดังกล่าวไปยังแบ็กเอนด์เพื่อสร้างบัญชีให้เสร็จสมบูรณ์