إذا كنت تتيح تسجيل الدخول باستخدام حسابات Google، يمكنك استخدام برنامج تسجيل الدخول باستخدام ميزة "نقرة واحدة" لمنح المستخدمين تجربة إنشاء حساب سلسة لا تخرجهم من سياق تطبيقك.
عند عرض واجهة مستخدم One Tap، يُطلب من المستخدمين إنشاء حساب جديد في تطبيقك باستخدام أحد حسابات Google على أجهزتهم. إذا اختار المستخدم المتابعة، ستحصل على رمز مميّز للتعريف يتضمّن معلومات الملف الشخصي الأساسية، مثل الاسم وصورة الملف الشخصي وعنوان البريد الإلكتروني الذي تم التحقّق منه، ويمكنك استخدام هذه المعلومات لإنشاء الحساب الجديد.
يتألف تنفيذ ميزة إنشاء حساب بنقرة واحدة من جزأين:
- دمج عميل One Tap في تطبيقك، وهو ما يتم شرحه في هذه الصفحة يتشابه هذا الإجراء في الغالب مع استخدام ميزة تسجيل الدخول باستخدام ميزة "نقرة واحدة"، ولكن مع بعض الاختلافات في الإعدادات.
- إضافة إمكانية إنشاء حسابات مستخدمين من رموز تعريف Google المميّزة إلى الخلفية، وهو ما تتم مناقشته في استخدام الرموز المميّزة للرقم التعريفي في الخلفية.
أين يمكنني استخدام ميزة "الاشتراك بنقرة واحدة"؟
أفضل مكان لتقديم ميزة "الاشتراك بنقرة واحدة" للمستخدمين هو في سياق يتيح فيه تسجيل الدخول ميزات جديدة. أولاً، حاوِل تسجيل دخول المستخدم باستخدام بيانات اعتماد محفوظة. إذا لم يتم العثور على بيانات اعتماد محفوظة، يمكنك عرض إنشاء حساب جديد للمستخدم.
قبل البدء
أعِدّ مشروعك على Google Cloud Console ومشروع Android كما هو موضّح في مقالة البدء في استخدام ميزة "تسجيل الدخول باستخدام ميزة "نقرة واحدة"".
1. ضبط عميل One Tap
لضبط عميل ميزة "نقرة واحدة" لإنشاء الحساب، اتّبِع الخطوات التالية:
- عدم تفعيل طلبات بيانات اعتماد كلمة المرور (لا يمكن الاشتراك بنقرة واحدة إلا من خلال المصادقة المستندة إلى الرمز المميّز).
يمكنك تفعيل طلبات الرموز المميّزة لتعريف Google باستخدام
setGoogleIdTokenRequestOptions()وهذه الإعدادات:- اضبط معرِّف عميل الخادم على المعرِّف الذي أنشأته في وحدة تحكّم Google Cloud. يُرجى العِلم أنّ هذا هو معرِّف العميل الخاص بالخادم، وليس معرِّف العميل الخاص بجهاز Android.
- اضبط العميل لعرض جميع حسابات 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. تتبُّع إلغاء واجهة مستخدم ميزة "بنقرة واحدة"
يجب تتبُّع ما إذا كان المستخدم قد رفض الاشتراك باستخدام ميزة "نقرة واحدة" من خلال إغلاق الطلب أو النقر خارجه. على سبيل المثال، يمكنك استخدام سمة منطقية لنشاطك. (يُرجى الاطّلاع على قسم إيقاف عرض واجهة مستخدم ميزة "نقرة واحدة" أدناه).
3- عرض واجهة مستخدم الاشتراك باستخدام ميزة "نقرة واحدة"
إذا لم يرفض المستخدم استخدام ميزة "بنقرة واحدة" لإنشاء حساب جديد، يمكنك استدعاء طريقة beginSignIn() الخاصة بعنصر العميل وإرفاق المستمعين إلى Task التي يتم عرضها. تنفّذ التطبيقات هذه الخطوة عادةً عندما لا يعثر طلب تسجيل الدخول باستخدام ميزة "نقرة واحدة" على أي بيانات اعتماد محفوظة، أي في أداة معالجة الأخطاء لطلب تسجيل الدخول:
- Success listener: يستدعي عميل One Tap أداة الاستماع إلى النجاح إذا كان
المستخدم قد أعدّ حسابًا واحدًا أو أكثر من حسابات Google على الجهاز. في مستمع النجاح، احصل على intent المؤجّلة من نتيجة
Taskومرِّرها إلىstartIntentSenderForResult()لبدء واجهة مستخدم One Tap. أداة معالجة حالات تعذُّر تسجيل الدخول: إذا لم يكن لدى المستخدم أي حسابات على Google على الجهاز، يستدعي عميل One Tap أداة معالجة حالات تعذُّر تسجيل الدخول. في هذه الحالة، ليس عليك اتخاذ أي إجراء، بل يمكنك مواصلة تقديم تجربة تسجيل الخروج من التطبيق، ويمكن للمستخدم الاشتراك من خلال عملية إنشاء الحساب العادية.
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. إذا رفض المستخدم الاشتراك، سواء من خلال إغلاق واجهة مستخدم One Tap أو النقر خارجها، ستظهر النتيجة مع الرمز RESULT_CANCELED. يجب أن يتعامل تطبيقك مع كلا الاحتمالين.
إنشاء حساب باستخدام رمز مميّز لرقم تعريف Google
إذا اختار المستخدم الاشتراك باستخدام حساب Google، يمكنك الحصول على رمز مميّز لرقم التعريف
للمستخدم من خلال تمرير بيانات intent من onActivityResult() إلى طريقة getSignInCredentialFromIntent()
لعميل One Tap. ستتضمّن بيانات الاعتماد سمة 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 أو استخدام طريقة أخرى.
من المهم تنفيذ حدّ معدّل طلبات تسجيل الدخول باستخدام ميزة "نقرة واحدة". وإذا لم تفعل ذلك، وألغى المستخدم عدة طلبات متتالية، لن يطلب عميل 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})")
}
}
}
}
}
}
// ...
}
الخطوات التالية
عندما يكمل المستخدم عملية الاشتراك باستخدام ميزة "نقرة واحدة"، ستحصل على رمز مميّز لرقم تعريف Google، والذي يتضمّن بعض المعلومات الأساسية للملف الشخصي: عنوان البريد الإلكتروني للمستخدم واسمه الكامل وعنوان URL لصورة الملف الشخصي. بالنسبة إلى العديد من التطبيقات، تكون هذه المعلومات كافية لمصادقة المستخدم في الخلفية وإنشاء حساب جديد.
إذا كنت بحاجة إلى معلومات إضافية لإكمال عملية إنشاء الحساب، مثل تاريخ ميلاد المستخدم، يمكنك عرض مسار تفاصيل الاشتراك للمستخدم، حيث تطلب هذه المعلومات الإضافية، ثم إرسالها إلى الخلفية لإكمال عملية إنشاء الحساب.