Crie novas contas com um toque

Se você oferece suporte ao login com Contas do Google, use o cliente de login com um toque para oferecer aos usuários uma experiência de criação de conta sem complicações que nunca os tira do contexto do app.

IU de inscrição com um toque

Quando você mostra a interface do One Tap, os usuários recebem uma solicitação para criar uma nova conta no seu app usando uma das Contas do Google no dispositivo. Se o usuário optar por continuar, você vai receber um token de ID com informações básicas do perfil, como nome, foto do perfil e endereço de e-mail verificado, que podem ser usadas para criar a nova conta.

A implementação da criação de conta com um toque tem duas partes:

  • Integrar o cliente do One Tap ao seu app, conforme descrito nesta página. Isso é quase igual ao uso do login com um toque, mas com algumas diferenças na configuração.
  • Adicionar ao back-end a capacidade de criar contas de usuário com base em tokens de ID do Google, conforme discutido em Como usar tokens de ID no back-end.

Onde devo usar a inscrição com um toque?

O lugar mais impactante para oferecer a inscrição com um toque aos usuários é em um contexto em que o login ativa novos recursos. Primeiro, tente fazer login do usuário com uma credencial salva. Se nenhuma credencial salva for encontrada, ofereça a criação de uma nova conta para o usuário.

Antes de começar

Configure seu projeto do console do Google Cloud e o projeto do Android conforme descrito em Começar a usar o login com um toque.

1. Configurar o cliente do One Tap

Para configurar o cliente do One Tap para a criação de contas, faça o seguinte:

  • Não ative as solicitações de credenciais de senha. A inscrição com um toque só é possível com a autenticação baseada em token.
  • Ative as solicitações de token de ID do Google usando setGoogleIdTokenRequestOptions() e estas configurações:

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. Acompanhar o cancelamento da interface do One Tap

É preciso acompanhar se o usuário já recusou o uso da inscrição com um toque, fechando o aviso ou tocando fora dele. Por exemplo, é possível usar uma propriedade booleana da atividade. Consulte Parar de exibir a interface do One Tap abaixo.

3. Mostrar a interface de inscrição com um toque

Se o usuário não tiver recusado o uso do recurso Um Toque para criar uma nova conta, chame o método beginSignIn() do objeto cliente e anexe listeners ao Task que ele retorna. Os apps normalmente realizam essa etapa quando uma solicitação de login com um toque não encontra credenciais salvas, ou seja, no listener de falha da solicitação de login:

  • Listener de sucesso: o cliente do One Tap chama o listener de sucesso se o usuário tiver uma ou mais Contas do Google configuradas no dispositivo. No listener de sucesso, receba a intent pendente do resultado de Task e transmita-a para startIntentSenderForResult() para iniciar a IU do One Tap.
  • Failure listener: se o usuário não tiver Contas do Google no dispositivo, o cliente do One Tap vai chamar o listener de falha. Nesse caso, nenhuma ação é necessária: continue apresentando a experiência de desconexão do app, e o usuário poderá se inscrever com o fluxo normal de criação de conta.

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. Processar a resposta do usuário

A resposta do usuário ao prompt de inscrição com um toque será informada ao app usando o método onActivityResult() da atividade. Se o usuário optar por criar uma conta, o resultado será um token de ID do Google. Se o usuário recusar a inscrição, fechando a interface do One Tap ou tocando fora dela, o resultado vai retornar com o código RESULT_CANCELED. Seu app precisa lidar com as duas possibilidades.

Criar uma conta com um token de ID do Google

Se o usuário optar por se inscrever com uma Conta do Google, você poderá receber um token de ID para ele transmitindo os dados de intent de onActivityResult() para o método getSignInCredentialFromIntent() do cliente com Um Toque. A credencial terá uma propriedade googleIdToken não nula.

Use o token de ID para criar uma conta no back-end (consulte Autenticar com um back-end usando tokens de ID) e faça login do usuário.

A credencial também contém outros detalhes que você solicitou, como o número de telefone verificado da conta, se disponível.

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

Parar de mostrar a IU do recurso Um Toque

Se o usuário recusar o login, a chamada para getSignInCredentialFromIntent() vai gerar uma ApiException com um código de status CommonStatusCodes.CANCELED. Quando isso acontecer, interrompa temporariamente a exibição da interface de login com um toque para não incomodar os usuários com solicitações repetidas. O exemplo a seguir faz isso definindo uma propriedade na atividade, que é usada para determinar se o usuário deve receber o login com um toque. No entanto, você também pode salvar um valor em SharedPreferences ou usar outro método.

É importante implementar sua própria limitação de taxa de solicitações de login com um toque. Se você não fizer isso e um usuário cancelar várias solicitações seguidas, o cliente do One Tap não vai solicitar o usuário pelas próximas 24 horas.

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

Próximas etapas

Quando um usuário conclui o fluxo de inscrição com um toque, você recebe um token de ID do Google, que inclui algumas informações básicas do perfil: o endereço de e-mail, o nome completo e o URL da foto do perfil do usuário. Para muitos apps, essas informações são suficientes para autenticar o usuário no back-end e criar uma nova conta.

Se você precisar de mais informações para concluir a criação da conta, como a data de nascimento do usuário, apresente um fluxo de detalhes de inscrição em que você solicita essas informações adicionais. Em seguida, envie-as para o back-end para concluir a criação da conta.