با یک ضربه حساب جدید ایجاد کنید

اگر از ورود با حساب‌های گوگل پشتیبانی می‌کنید، می‌توانید از کلاینت ورود با یک لمس (One Tap sign-in) نیز استفاده کنید تا به کاربران خود یک تجربه ایجاد حساب کاربری بدون دردسر ارائه دهید که هرگز آنها را از چارچوب برنامه شما خارج نمی‌کند.

رابط کاربری ثبت نام با یک لمس

وقتی رابط کاربری One Tap را نمایش می‌دهید، از کاربران خواسته می‌شود که با استفاده از یکی از حساب‌های گوگل موجود در دستگاه خود، یک حساب کاربری جدید در برنامه شما ایجاد کنند. اگر کاربر ادامه را انتخاب کند، یک شناسه با اطلاعات اولیه پروفایل - نام، عکس پروفایل و آدرس ایمیل تأیید شده آنها - دریافت می‌کنید که می‌توانید از آن برای ایجاد حساب کاربری جدید استفاده کنید.

پیاده‌سازی ایجاد حساب کاربری با یک لمس (One Tap) دو بخش دارد:

  • ادغام کلاینت One Tap در برنامه شما، که در این صفحه توضیح داده شده است. این تقریباً مشابه استفاده از ورود به سیستم One Tap است، اما با برخی تفاوت‌ها در پیکربندی.
  • اضافه کردن قابلیت ایجاد حساب‌های کاربری از توکن‌های شناسه گوگل به بخش مدیریت، که در بخش استفاده از توکن‌های شناسه در بخش مدیریت مورد بحث قرار گرفته است.

کجا باید از ثبت نام با One Tap استفاده کنم؟

مؤثرترین مکان برای ارائه ثبت نام با یک لمس به کاربران، در شرایطی است که ورود به سیستم، ویژگی‌های جدیدی را فعال می‌کند. ابتدا، سعی کنید کاربر را با یک اعتبارنامه ذخیره شده وارد سیستم کنید. اگر هیچ اعتبارنامه ذخیره شده‌ای پیدا نشد، پیشنهاد ایجاد یک حساب کاربری جدید برای کاربر را بدهید.

قبل از اینکه شروع کنی

پروژه کنسول Google APIs و پروژه اندروید خود را همانطور که در «شروع با ورود با یک ضربه» توضیح داده شده است، تنظیم کنید.

۱. پیکربندی کلاینت One Tap

برای پیکربندی کلاینت One Tap برای ایجاد حساب کاربری، موارد زیر را انجام دهید:

  • درخواست‌های اعتبارسنجی با رمز عبور را فعال نکنید. (ثبت‌نام با یک ضربه فقط با احراز هویت مبتنی بر توکن امکان‌پذیر است.)
  • درخواست‌های توکن شناسه گوگل را با استفاده از setGoogleIdTokenRequestOptions() و این تنظیمات فعال کنید:

جاوا

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();

      // ...
  }
}

کاتلین

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

۲. لغو رابط کاربری One Tap را پیگیری کنید

شما باید با بستن اعلان یا ضربه زدن به خارج از آن، پیگیری کنید که آیا کاربر قبلاً از استفاده از ثبت نام One Tap خودداری کرده است یا خیر. این می‌تواند به سادگی یک ویژگی بولی از Activity شما باشد. (به بخش «توقف نمایش رابط کاربری One Tap» در زیر مراجعه کنید.)

۳. رابط کاربری ثبت نام با یک لمس را نمایش دهید

اگر کاربر استفاده از One Tap برای ایجاد یک حساب کاربری جدید را رد نکرده باشد، متد beginSignIn() شیء کلاینت را فراخوانی کنید و شنونده‌ها را به Task که برمی‌گرداند، متصل کنید. برنامه‌ها معمولاً این مرحله را زمانی انجام می‌دهند که درخواست ورود به سیستم One Tap هیچ اعتبارنامه ذخیره‌شده‌ای را پیدا نمی‌کند - یعنی در شنونده ناموفق درخواست ورود به سیستم.

اگر کاربر یک یا چند حساب گوگل روی دستگاه خود تنظیم کرده باشد، کلاینت One Tap، شنونده موفقیت (success listener) را فراخوانی می‌کند. در شنونده موفقیت، intent در حال انتظار را از نتیجه Task دریافت کرده و آن را به startIntentSenderForResult() ارسال کنید تا رابط کاربری One Tap آغاز شود.

اگر کاربر هیچ حساب گوگلی روی دستگاه نداشته باشد، کلاینت One Tap شنونده‌ی خطا را فراخوانی می‌کند. در این حالت، هیچ اقدامی لازم نیست: می‌توانید به سادگی به ارائه‌ی تجربه‌ی خروج از برنامه ادامه دهید و کاربر می‌تواند با روند عادی ایجاد حساب کاربری، ثبت‌نام کند.

جاوا

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());
            }
        });

کاتلین

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)
    }

۴. پاسخ کاربر را مدیریت کنید

پاسخ کاربر به درخواست ثبت نام One Tap با استفاده از متد onActivityResult() در Activity به برنامه شما گزارش می‌شود. اگر کاربر تصمیم به ایجاد حساب کاربری گرفته باشد، نتیجه یک توکن Google ID خواهد بود. اگر کاربر از ثبت نام خودداری کرده باشد، چه با بستن رابط کاربری One Tap و چه با ضربه زدن به خارج از آن، نتیجه با کد RESULT_CANCELED برگردانده می‌شود. برنامه شما باید هر دو احتمال را مدیریت کند.

ایجاد حساب کاربری با توکن گوگل آیدی

اگر کاربر تصمیم به ثبت نام با حساب گوگل گرفته باشد، می‌توانید با ارسال داده‌های intent از onActivityResult() به متد getSignInCredentialFromIntent() کلاینت One Tap، یک شناسه کاربر (ID token) دریافت کنید. این اعتبارنامه دارای یک ویژگی googleIdToken غیر تهی خواهد بود.

از توکن شناسه برای ایجاد یک حساب کاربری در بخش مدیریت خود استفاده کنید (به بخش احراز هویت با استفاده از توکن‌های شناسه در بخش مدیریت مراجعه کنید) و کاربر را وارد سیستم کنید.

این اعتبارنامه همچنین شامل هرگونه جزئیات اضافی مورد درخواست شما، مانند شماره تلفن تأیید شده حساب در صورت وجود، می‌شود.

جاوا

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;
      }
  }
}

کاتلین

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

نمایش رابط کاربری One Tap را متوقف کنید

اگر کاربر از ورود به سیستم خودداری کند، فراخوانی تابع getSignInCredentialFromIntent() یک ApiException با کد وضعیت CommonStatusCodes.CANCELED ایجاد می‌کند. در این صورت، باید نمایش رابط کاربری ورود با یک ضربه (One Tap) را موقتاً متوقف کنید تا کاربران خود را با درخواست‌های مکرر آزار ندهید. مثال زیر این کار را با تنظیم یک ویژگی در Activity انجام می‌دهد که از آن برای تعیین اینکه آیا ورود با یک ضربه را به کاربر پیشنهاد دهد یا خیر، استفاده می‌کند. با این حال، می‌توانید مقداری را در SharedPreferences ذخیره کنید یا از روش دیگری استفاده کنید.

مهم است که محدودیت سرعت خود را برای اعلان‌های ورود با One Tap پیاده‌سازی کنید. اگر این کار را نکنید و کاربر چندین اعلان را پشت سر هم لغو کند، کلاینت One Tap تا ۲۴ ساعت آینده اعلانی به کاربر ارسال نخواهد کرد.

جاوا

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;
      }
  }
}

کاتلین

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 تصویر پروفایل. برای بسیاری از برنامه‌ها، این اطلاعات برای تأیید اعتبار کاربر در backend و ایجاد یک حساب کاربری جدید کافی است.

اگر برای تکمیل ایجاد حساب کاربری به اطلاعات اضافی نیاز دارید - مثلاً تاریخ تولد کاربر - یک جریان جزئیات ثبت نام را به کاربر ارائه دهید، جایی که این اطلاعات اضافی را درخواست می‌کنید. سپس، آن را برای تکمیل ایجاد حساب کاربری به بخش مدیریت خود ارسال کنید.