إنشاء حسابات جديدة بنقرة واحدة

إذا كنت تتيح تسجيل الدخول باستخدام حسابات Google، يمكنك تسجيل الدخول بنقرة واحدة. العميل أيضًا لمنح المستخدمين تجربة سلسة في إنشاء الحسابات لا تأخذها أبدًا خارج سياق تطبيقك.

واجهة مستخدم الاشتراك بنقرة واحدة

عند عرض واجهة المستخدم بنقرة واحدة، يُطلب من المستخدمين إنشاء حساب جديد باستخدام تطبيقك باستخدام أحد حسابات Google على جهازه. إذا اختار المستخدم للمتابعة، ستحصل على رمز مميز للمعرف يتضمن معلومات الملف الشخصي الأساسية - الاسم وصورة الملف الشخصي وعنوان البريد الإلكتروني الذي تم إثبات ملكيته—والتي يمكنك استخدامها لإنشاء الحساب الجديد.

ينطوي تنفيذ إنشاء الحساب بنقرة واحدة على جزأين:

  • دمج برنامج "نقرة واحدة" مع تطبيقك، والموضّح في هذه الصفحة تتشابه هذه الميزة في الغالب مع استخدام تسجيل الدخول بنقرة واحدة، ولكن مع بعض الاختلافات في التكوين.
  • إضافة إمكانية إنشاء حسابات مستخدمين من معرِّف Google إلى الخلفية التي تمت مناقشتها في مقالة استخدام رموز التعريف في الخلفية.

أين يجب الاشتراك في ميزة "نقرة واحدة"؟

يُعد المكان الأكثر تأثيرًا لتقديم إمكانية الاشتراك بنقرة واحدة للمستخدمين هو السياق الذي سيؤدي تسجيل الدخول إلى تفعيل ميزات جديدة. أولاً، حاول تسجيل دخول المستخدم من خلال بيانات اعتماد محفوظة. إذا لم يتم العثور على أي بيانات اعتماد محفوظة، يمكنك اقتراح إنشاء حساب المستخدم.

قبل البدء

إعداد مشروع وحدة تحكّم Google APIs ومشروع Android كما هو موضَّح في بدء تسجيل الدخول باستخدام ميزة "نقرة واحدة"

1. ضبط إعدادات برنامج "نقرة واحدة"

لضبط برنامج "نقرة واحدة" لإنشاء الحساب، عليك اتّباع الخطوات التالية:

  • عدم تفعيل طلبات بيانات اعتماد كلمة المرور (يمكن الاشتراك بنقرة واحدة فقط باستخدام المصادقة القائمة على الرمز).
  • تفعيل طلبات الرموز المميّزة لمعرّف 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. تتبُّع عملية إلغاء واجهة المستخدم بنقرة واحدة

يجب معرفة ما إذا كان المستخدم قد رفض استخدام ميزة "نقرة واحدة" أم لا. الاشتراك من خلال إغلاق الطلب أو النقر خارجه يمكن أن يكون هذا بسيطًا كخاصية منطقية لنشاطك. (راجع إيقاف عرض ميزة "نقرة واحدة" واجهة المستخدم، أدناه).

3- عرض واجهة المستخدم الخاصة بالاشتراك بنقرة واحدة

إذا لم يرفض المستخدم استخدام ميزة "نقرة واحدة" لإنشاء حساب جديد، عليك طلب طريقة beginSignIn() لكائن العميل، وإرفاق المستمعين بعنصر Task وإرجاعه. تنفِّذ التطبيقات هذه الخطوة عادةً إذا لم يعثر طلب تسجيل الدخول بنقرة واحدة على أي بيانات اعتماد محفوظة، أي في أداة معالجة رسائل الخطأ لعملية تسجيل الدخول. طلبك.

سيتصل عميل "نقرة واحدة" بمستمع النجاح إذا كان المستخدم لديه واحد أو أكثر حسابات Google التي تم إعدادها على الجهاز في المستمع الناجح، احصل على نية من نتيجة Task وتمريرها إلى startIntentSenderForResult() إلى بدء واجهة المستخدم بنقرة واحدة

إذا لم يكن لدى المستخدم أي حسابات 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. التعامل مع رد المستخدم

سيتم إبلاغ تطبيقك عن ردّ المستخدم على طلب الاشتراك في ميزة "نقرة واحدة" باستخدام طريقة onActivityResult() الخاصة بنشاطك. إذا اختار المستخدم إنشاء الخاص بك، ستكون النتيجة رمزًا مميزًا لمعرّف Google. إذا رفض المستخدم الاشتراك، سواء عن طريق إغلاق واجهة المستخدم بنقرة واحدة أو النقر خارجها، ستظهر النتيجة مع الرمز RESULT_CANCELED. ويجب أن يتعامل تطبيقك مع كلا الاحتمالَين.

إنشاء حساب باستخدام رمز مميز لمعرّف Google

إذا اختار المستخدم الاشتراك باستخدام حساب Google، يمكنك الحصول على رمز معرّف مميز المستخدم من خلال تمرير بيانات الأهداف من onActivityResult() إلى ميزة "نقرة واحدة" طريقة 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) {
                    // ...
            }
        }
    }
    // ...
}

إيقاف عرض واجهة المستخدم بنقرة واحدة

إذا رفض المستخدم تسجيل الدخول، سيتم الاتصال برقم getSignInCredentialFromIntent(). ستعرض الرمز ApiException مع رمز الحالة CommonStatusCodes.CANCELED. عند حدوث ذلك، عليك مؤقتًا إيقاف عرض واجهة المستخدم لتسجيل الدخول بنقرة واحدة. حتى لا تزعج المستخدمين بمطالبات متكررة. المثال التالي عن طريق تعيين موقع على النشاط، والذي يتم استخدامه من أجل تحديد ما إذا كنت تريد السماح للمستخدم بتسجيل الدخول بنقرة واحدة ومع ذلك، يمكنك أيضًا حفظ قيمة في SharedPreferences أو استخدام طريقة أخرى.

من المهم أن تحدّ من معدّل تلقّي رسائل طلب تسجيل الدخول بنقرة واحدة. إذا لم تطلب ذلك، وألغى أحد المستخدمين عدة طلبات على التوالي، فسيطلب برنامج "نقرة واحدة" ولن يتم إرسال طلب إلى المستخدم خلال الـ 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})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

الخطوات التالية

عندما يكمل المستخدم عملية الاشتراك بنقرة واحدة، ستحصل على رمز مميز لمعرّف Google، والذي بعض معلومات الملف الشخصي الأساسية: عنوان البريد الإلكتروني للمستخدم والاسم الكامل وعنوان URL لصورة الملف الشخصي. ستكون هذه المعلومات كافية لكثير من التطبيقات مصادقة المستخدم في الخلفية وإنشاء حساب جديد.

إذا كنت بحاجة إلى معلومات إضافية لإكمال إنشاء الحساب، مثل تاريخ ميلاد المستخدم - اعرض للمستخدم تدفقًا لتفاصيل الاشتراك، حيث عليك طلب هذه المعلومات الإضافية. بعد ذلك، أرسله إلى الخلفية لإكمال إنشاء الحساب.