Twórz nowe konta jednym kliknięciem

Jeśli obsługujesz logowanie się przez konta Google, możesz użyć klienta logowania jednym dotknięciem, aby zapewnić użytkownikom bezproblemowy proces tworzenia kont i nigdy nie wyprowadzić ich z kontekstu aplikacji.

Interfejs rejestracji jednym dotknięciem

Gdy wyświetlisz interfejs One Tap, użytkownicy zostaną poproszeni o utworzenie nowego konta w aplikacji przy użyciu jednego z kont Google na swoich urządzeniach. Jeśli użytkownik zdecyduje się kontynuować, otrzymasz token identyfikatora z podstawowymi informacjami profilowymi (imię i nazwisko, zdjęcie profilowe i zweryfikowany adres e-mail), których możesz użyć do utworzenia nowego konta.

Wdrażanie tworzenia konta jednym dotknięciem składa się z 2 etapów:

  • Integracja klienta One Tap z aplikacją w sposób opisany na tej stronie. Działa to w większości tak samo jak w przypadku logowania jednym dotknięciem, ale występują pewne różnice w konfiguracji.
  • Dodanie do backendu możliwości tworzenia kont użytkowników przy użyciu tokenów identyfikatorów Google. Zostało to omówione w sekcji Używanie tokenów identyfikatorów w backendzie.

Gdzie należy używać rejestracji jednym dotknięciem?

Najlepszy sposób na oferowanie użytkownikom rejestracji jednym dotknięciem to sytuacja, w której logowanie spowodowałoby włączenie nowych funkcji. Najpierw spróbuj zalogować użytkownika przy użyciu zapisanych danych logowania. Jeśli nie znaleziono zapisanych danych logowania, zaproponuj utworzenie nowego konta dla użytkownika.

Zanim zaczniesz

Skonfiguruj projekt w konsoli interfejsów API Google i projekt Androida w sposób opisany w artykule Pierwsze kroki z logowaniem się jednym dotknięciem.

1. Konfigurowanie klienta One Tap

Aby skonfigurować klienta One Tap na potrzeby tworzenia konta:

  • Nie włączaj żądań danych logowania na hasło. (Rejestracja jednym dotknięciem jest możliwa tylko w przypadku uwierzytelniania za pomocą tokenów).
  • Włącz żądania tokena tożsamości Google za pomocą setGoogleIdTokenRequestOptions() i tych ustawień:

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. Śledzenie anulowania subskrypcji jednym dotknięciem

Sprawdź, czy użytkownik odmówił już rejestracji jednym dotknięciem, zamykając potwierdzenie lub klikając poza nim. Może to być tak proste jak właściwość wartości logicznej aktywności. (patrz sekcja Zatrzymywanie wyświetlania interfejsu jednym dotknięciem poniżej).

3. Wyświetl interfejs rejestracji jednym dotknięciem

Jeśli użytkownik nie odmówił utworzenia nowego konta za pomocą jednego dotknięcia, wywołaj metodę beginSignIn() obiektu klienta i dołącz detektory do zwróconego obiektu Task. Aplikacje zwykle wykonują ten krok, gdy żądanie logowania jednym dotknięciem nie znajduje żadnych zapisanych danych logowania, czyli w odbiorniku błędów logowania.

Klient One Tap wywołuje detektor sukcesu, jeśli użytkownik ma na urządzeniu skonfigurowane co najmniej jedno konto Google. W detektorze sukcesu pobierz oczekującą intencję z wyniku Task i przekaż ją do startIntentSenderForResult(), aby uruchomić interfejs jednym dotknięciem.

Jeśli użytkownik nie ma żadnych kont Google na urządzeniu, klient One Tap wywoła detektor błędów. W takim przypadku nie musisz nic robić: możesz dalej prezentować aplikację jako niezalogowaną, a użytkownik będzie mógł się zarejestrować, postępując zgodnie ze zwykłym procesem tworzenia konta.

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. Obsługa odpowiedzi użytkownika

Reakcja użytkownika na prośbę o rejestrację jednym dotknięciem zostanie przekazana do aplikacji za pomocą metody onActivityResult() aktywności. Jeśli użytkownik zdecyduje się utworzyć konto, wynikiem będzie token tożsamości Google. Jeśli użytkownik odmówił rejestracji (przez zamknięcie interfejsu jednym dotknięciem lub dotknięcie poza nim), w wyniku pojawi się kod RESULT_CANCELED. Aplikacja musi obsługiwać obie te możliwości.

Tworzenie konta z użyciem tokena tożsamości Google

Jeśli użytkownik zdecyduje się zarejestrować się przez konto Google, możesz uzyskać dla niego token tożsamości, przekazując dane intencji z onActivityResult() do metody getSignInCredentialFromIntent() klienta jednym dotknięciem. Dane logowania będą miały niezerową wartość googleIdToken.

Użyj tokena identyfikatora, aby utworzyć konto w backendzie (zobacz Uwierzytelnianie za pomocą backendu przy użyciu tokenów identyfikatorów) i zaloguj użytkownika.

Dane logowania zawierają też wszelkie dodatkowe informacje, o które prosisz, takie jak zweryfikowany numer telefonu na koncie, o ile jest dostępny.

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) {
                    // ...
            }
        }
    }
    // ...
}

Przestań wyświetlać interfejs jednym dotknięciem

Jeśli użytkownik odmówił zalogowania się, połączenie z numerem getSignInCredentialFromIntent() spowoduje zgłoszenie błędu ApiException z kodem stanu CommonStatusCodes.CANCELED. W takim przypadku zatrzymaj wyświetlanie interfejsu logowania jednym dotknięciem, aby nie drażnić użytkowników powtarzających się prośbami. W tym przykładzie pozwala to ustawić w Aktywności jako właściwość, która określa, czy należy udostępnić użytkownikowi logowanie jednym dotknięciem. Możesz też zapisać wartość w elemencie SharedPreferences lub użyć innej metody.

Ważne jest, aby wdrożyć własne ograniczenie częstotliwości próśb o zalogowanie się za pomocą jednego dotknięcia. Jeśli tego nie zrobisz, a użytkownik anuluje kilka próśb z rzędu, klient One Tap nie poprosi użytkownika przez następne 24 godziny.

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})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

Dalsze kroki

Gdy użytkownik wykona rejestrację jednym dotknięciem, otrzymasz token identyfikatora Google, który będzie zawierał podstawowe informacje z profilu: adres e-mail użytkownika, jego imię i nazwisko oraz adres URL zdjęcia profilowego. W przypadku wielu aplikacji te informacje wystarczą do uwierzytelnienia użytkownika w backendzie i utworzenia nowego konta.

Jeśli do utworzenia konta potrzebujesz dodatkowych informacji – na przykład daty urodzenia – przekaż użytkownikowi informacje o rejestracji, w ramach którego o to prosisz. Następnie prześlij je do swojego backendu, aby dokończyć tworzenie konta.