สร้างบัญชีใหม่ด้วยการแตะเพียงครั้งเดียว

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

UI การลงชื่อสมัครใช้ด้วยการแตะเพียงครั้งเดียว

เมื่อคุณแสดง UI ของ One Tap ผู้ใช้จะได้รับแจ้งให้สร้างบัญชีใหม่ด้วย แอปของคุณโดยใช้บัญชี Google บัญชีใดบัญชีหนึ่งในอุปกรณ์ของตน หากผู้ใช้เลือก ในการดำเนินการต่อ คุณจะได้รับโทเค็นรหัสที่มีข้อมูลโปรไฟล์พื้นฐาน เช่น รูปภาพโปรไฟล์ และอีเมลที่ได้รับการยืนยัน ซึ่งคุณสามารถใช้เพื่อ สร้างบัญชีใหม่

การสร้างบัญชีด้วย One Tap มี 2 ส่วนดังนี้

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

ฉันควรใช้การลงชื่อสมัครใช้ด้วย One Tap ที่ไหนบ้าง

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

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

ตั้งค่าโปรเจ็กต์คอนโซล Google APIs และโปรเจ็กต์ Android ตามที่อธิบายไว้ ในส่วนเริ่มต้นใช้งานการลงชื่อเข้าใช้ด้วย One Tap

1. กำหนดค่าไคลเอ็นต์ One Tap

หากต้องการกำหนดค่าไคลเอ็นต์ One Tap สำหรับการสร้างบัญชี ให้ทำดังนี้

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

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() ของออบเจ็กต์ไคลเอ็นต์ และแนบ Listener กับ Task ของออบเจ็กต์ดังกล่าว ที่เกินออกมา ตามปกติแอปจะดำเนินการขั้นตอนนี้เมื่อคำขอลงชื่อเข้าใช้ด้วย One Tap ไม่พบ ข้อมูลรับรองที่บันทึกไว้ทั้งหมด ซึ่งก็คือใน Listener ที่ไม่สำเร็จของการลงชื่อเข้าใช้ อีกครั้ง

ไคลเอ็นต์ One Tap จะโทรหา Listener ที่สำเร็จ ถ้าผู้ใช้มีอย่างน้อย 1 รายการ ตั้งค่าบัญชี Google ในอุปกรณ์แล้ว ใน Listener ที่สำเร็จ ให้ใช้สถานะรอดำเนินการ Intent จากผลลัพธ์ Task และส่งไปยัง startIntentSenderForResult() ไปยัง เริ่มใช้ UI ด้วยการแตะเพียงครั้งเดียว

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

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 หากผู้ใช้ปฏิเสธที่จะลงชื่อสมัครใช้ ด้วยการปิด One Tap UI หรือแตะด้านนอก ผลลัพธ์จะแสดงขึ้นมา โดยใช้รหัส RESULT_CANCELED แอปของคุณต้องรับมือกับทั้ง 2 ความเป็นไปได้

สร้างบัญชีด้วยโทเค็นรหัส Google

หากผู้ใช้เลือกที่จะลงชื่อสมัครใช้ด้วยบัญชี Google คุณสามารถรับโทเค็นรหัสสำหรับ ผู้ใช้โดยส่งข้อมูล Intent จาก onActivityResult() ไปยัง One Tap เมธอด getSignInCredentialFromIntent() ของไคลเอ็นต์ได้ ข้อมูลเข้าสู่ระบบจะมีแอตทริบิวต์ พร็อพเพอร์ตี้ 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 ด้วยการแตะเพียงครั้งเดียว

หากผู้ใช้ปฏิเสธการลงชื่อเข้าใช้ การโทรไปที่ getSignInCredentialFromIntent() จะแสดง ApiException ที่มีรหัสสถานะ CommonStatusCodes.CANCELED เมื่อเกิดกรณีนี้ขึ้น คุณควรหยุดแสดง UI การลงชื่อเข้าใช้ด้วย One Tap ชั่วคราว เพื่อไม่ให้ผู้ใช้รู้สึกรำคาญด้วยข้อความแจ้งซ้ำๆ ตัวอย่างต่อไปนี้ คุณสามารถทำได้โดยการตั้งค่าพร็อพเพอร์ตี้ใน Activity เพื่อ ตัดสินใจว่าจะเสนอการลงชื่อเข้าใช้ด้วย One Tap ให้แก่ผู้ใช้หรือไม่ อย่างไรก็ตาม คุณสามารถ บันทึกค่าลงใน SharedPreferences หรือใช้วิธีอื่น

คุณควรใช้การจำกัดอัตราคำขอลงชื่อเข้าใช้ด้วย One Tap ด้วยตัวเอง หากไม่ยกเลิก และผู้ใช้ยกเลิกข้อความแจ้งหลายรายการติดต่อกัน ไคลเอ็นต์ 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 ประกอบด้วยข้อมูลโปรไฟล์พื้นฐาน ได้แก่ ที่อยู่อีเมล ชื่อเต็มของผู้ใช้ และ URL ของรูปโปรไฟล์ สำหรับแอปจำนวนมาก ข้อมูลเพียงเท่านี้ก็เพียงพอแล้วที่คุณจะทำสิ่งต่อไปนี้ ตรวจสอบสิทธิ์ผู้ใช้ในแบ็กเอนด์ และสร้างบัญชีใหม่

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