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

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

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

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

يتضمّن تنفيذ ميزة "نقرة واحدة" لإنشاء الحساب جزأَين:

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

أين يجب أن أستخدم ميزة "الاشتراك باستخدام حساب Google"؟

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

قبل البدء

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

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

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

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

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

‫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 لصورة ملفه الشخصي. بالنسبة إلى العديد من التطبيقات، تكون هذه المعلومات كافية لمصادقة المستخدم على النظام الخلفي وإنشاء حساب جديد.

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