ワンタップで新しいアカウントを作成できます

Google アカウントでのログインをサポートしている場合は、One Tap ログイン クライアントを使用して、アプリのコンテキストから離れることなく、スムーズにアカウントを作成できるエクスペリエンスをユーザーに提供することもできます。

ワンタップ登録 UI

ワンタップ UI を表示すると、デバイス上のいずれかの Google アカウントを使用してアプリの新しいアカウントを作成するようユーザーに求められます。ユーザーが続行を選択すると、基本的なプロフィール情報(名前、プロフィール写真、確認済みのメールアドレス)を含む ID トークンが取得されます。このトークンを使用して新しいアカウントを作成できます。

ワンタップ アカウント作成の実装は、次の 2 つの部分で構成されます。

  • このページで説明する、ワンタップ クライアントをアプリに統合する。これは One Tap サインインを使用する場合とほぼ同じですが、構成に違いがあります。
  • バックエンドに Google ID トークンからユーザー アカウントを作成する機能を追加する。これについては、バックエンドで ID トークンを使用するで説明します。

One Tap サインアップはどこで使用すればよいですか?

One Tap サインアップをユーザーに提供する最も効果的な場所は、ログインすることで新機能が有効になるコンテキストです。まず、保存済みの認証情報を使用してユーザーをログインさせます。保存済みの認証情報が見つからない場合は、新しいアカウントを作成するようユーザーに提案します。

始める前に

One Tap サインインを始めるの手順に沿って、Google API コンソール プロジェクトと Android プロジェクトを設定します。

1. ワンタップ クライアントを構成する

アカウント作成用にワンタップ クライアントを構成するには、次の操作を行います。

  • パスワード認証情報のリクエストを有効にしないでください。(One Tap サインアップは、トークンベースの認証でのみ可能です)。
  • setGoogleIdTokenRequestOptions() と次の設定を使用して、Google ID トークン リクエストを有効にします。

    • サーバー クライアント ID を、Google API コンソールで作成した ID に設定します。これは Android クライアント ID ではなく、サーバーのクライアント ID です。
    • デバイス上のすべての 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 サインアップの使用をすでに拒否しているかどうかを追跡する必要があります。これは、Activity のブール値プロパティとして簡単に実装できます。(下記の ワンタップ UI の表示を停止するをご覧ください)。

3. One Tap サインアップ UI を表示する

ユーザーがワンタップを使用して新しいアカウントを作成することを拒否していない場合は、クライアント オブジェクトの beginSignIn() メソッドを呼び出し、返された Task にリスナーをアタッチします。アプリは通常、One Tap サインイン リクエストで保存済みの認証情報が見つからない場合、つまりサインイン リクエストの失敗リスナーでこのステップを実行します。

デバイスに 1 つ以上の Google アカウントが設定されている場合、ワンタップ クライアントは成功リスナーを呼び出します。成功リスナーで、Task の結果から保留中のインテントを取得し、startIntentSenderForResult() に渡して ワンタップ UI を起動します。

デバイスに Google アカウントがない場合、ワンタップ クライアントは失敗リスナーを呼び出します。この場合、特別な操作は必要ありません。アプリのログアウト状態の画面を引き続き表示するだけで、ユーザーは通常のアカウント作成フローで登録できます。

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 サインアップ プロンプトに対するユーザーの応答は、Activity の onActivityResult() メソッドを使用してアプリに報告されます。ユーザーがアカウントの作成を選択した場合、結果は Google ID トークンになります。ユーザーが One Tap UI を閉じるか、その外側をタップして登録を拒否した場合、結果はコード RESULT_CANCELED で返されます。アプリは両方の可能性に対応する必要があります。

Google ID トークンでアカウントを作成する

ユーザーが Google アカウントで登録することを選択した場合は、onActivityResult() からのインテントデータを One Tap クライアントの getSignInCredentialFromIntent() メソッドに渡すことで、ユーザーの ID トークンを取得できます。認証情報には、null 以外の googleIdToken プロパティが含まれます。

ID トークンを使用してバックエンドでアカウントを作成し(ID トークンを使用して バックエンドで認証するを参照)、ユーザーをログインさせます。

認証情報には、アカウントの確認済み電話番号など、リクエストした追加の詳細情報も含まれます(利用可能な場合)。

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() の呼び出しは、ステータス コード CommonStatusCodes.CANCELED を含む ApiException をスローします。 この場合、ユーザーに繰り返しプロンプトが表示されて煩わしくならないように、One Tap サインイン UI の表示を一時的に停止する必要があります。次の例では、Activity にプロパティを設定することでこれを実現しています。このプロパティを使用して、ユーザーに One Tap サインインを提供するかどうかを判断します。ただし、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 など、基本的なプロフィール情報が含まれます。多くのアプリでは、この情報だけでバックエンドでユーザーを 認証し、新しいアカウントを作成できます。

アカウント作成を完了するために追加情報(ユーザーの生年月日など)が必要な場合は、登録の詳細フローを表示して、この追加情報をリクエストします。次に、バックエンドに送信してアカウント作成を完了します。