יצירת חשבונות חדשים בהקשה אחת

אם אתם תומכים בכניסה באמצעות חשבונות Google, אתם יכולים להשתמש בלקוח של "כניסה בלחיצה אחת" כדי לספק למשתמשים חוויית יצירת חשבון חלקה, בלי שהם יצטרכו לצאת מהאפליקציה.

ממשק משתמש להרשמה בלחיצה אחת

כשמציגים את ממשק המשתמש של One Tap, המשתמשים מתבקשים ליצור חשבון חדש באפליקציה באמצעות אחד מחשבונות Google במכשיר שלהם. אם המשתמש בוחר להמשיך, אתם מקבלים טוקן של מזהה עם פרטי פרופיל בסיסיים – השם, תמונת הפרופיל וכתובת האימייל המאומתת שלו – שבהם אתם יכולים להשתמש כדי ליצור את החשבון החדש.

הטמעת יצירת חשבון בלחיצה אחת כוללת שני חלקים:

  • שילוב הלקוח של One Tap באפליקציה, כפי שמתואר בדף הזה. התהליך הזה דומה מאוד לשימוש בכניסה בלחיצה אחת, אבל יש כמה הבדלים בהגדרות.
  • הוספת היכולת ליצור חשבונות משתמשים מטוקנים של מזהי Google לקצה העורפי, כפי שמתואר במאמר שימוש בטוקנים של מזהים בקצה העורפי.

איפה כדאי להשתמש בהרשמה בלחיצה אחת?

המקום הכי יעיל להציע למשתמשים הרשמה בלחיצה אחת הוא בהקשר שבו הכניסה תאפשר להם להשתמש בתכונות חדשות. קודם, נסו להכניס את המשתמש באמצעות פרטי כניסה שמורים. אם לא נמצאו פרטי כניסה שמורים, הציעו למשתמש ליצור חשבון חדש.

לפני שמתחילים

מגדירים את הפרויקט במסוף Google Cloud ואת פרויקט Android כמו שמתואר במאמר תחילת העבודה עם כניסה בלחיצה אחת.

1. הגדרת הלקוח של One Tap

כדי להגדיר את לקוח One Tap ליצירת חשבון, צריך לבצע את הפעולות הבאות:

  • לא להפעיל בקשות לפרטי כניסה באמצעות סיסמה. (הרשמה בלחיצה אחת אפשרית רק עם אימות מבוסס-אסימון).
  • מפעילים בקשות לאסימון מזהה של 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. מעקב אחרי ביטול ממשק המשתמש של One Tap

כדאי לעקוב אחרי המקרים שבהם המשתמש כבר סירב להשתמש בהרשמה בלחיצה אחת, על ידי סגירת ההודעה או לחיצה מחוץ לה. לדוגמה, אפשר להשתמש במאפיין בוליאני של הפעילות. (ראו הפסקת ההצגה של ממשק המשתמש של One Tap בהמשך).

3. הצגת ממשק המשתמש של ההרשמה בלחיצה אחת

אם המשתמש לא סירב להשתמש בכניסה בקליק אחד כדי ליצור חשבון חדש, צריך להפעיל את השיטה beginSignIn() של אובייקט הלקוח ולצרף מאזינים ל-Task שהוא מחזיר. בדרך כלל, האפליקציות מבצעות את השלב הזה כשבקשת כניסה בלחיצה אחת לא מוצאת פרטי כניסה שמורים – כלומר, במאזין הכשל של בקשת הכניסה:

  • מאזין להצלחה: לקוח 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() ל-method‏ getSignInCredentialFromIntent() של הלקוח של One Tap. לפרטי הכניסה יהיה מאפיין googleIdToken שאינו null.

משתמשים בטוקן של המזהה כדי ליצור חשבון בקצה העורפי (ראו אימות באמצעות קצה עורפי באמצעות טוקנים של מזהים) ומכניסים את המשתמש לחשבון.

פרטי הכניסה מכילים גם פרטים נוספים שביקשתם, כמו מספר הטלפון המאומת של החשבון, אם הוא זמין.

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

הפסקת ההצגה של ממשק המשתמש של One Tap

אם המשתמש סירב להיכנס, הקריאה ל-getSignInCredentialFromIntent() תפעיל ApiException עם קוד סטטוס CommonStatusCodes.CANCELED. במצב כזה, כדאי להפסיק זמנית את ההצגה של ממשק המשתמש של "כניסה בלחיצה אחת" כדי לא להציק למשתמשים עם בקשות חוזרות. בדוגמה הבאה, כדי לעשות את זה מגדירים מאפיין ב-Activity, שמשמש כדי לקבוע אם להציע למשתמש כניסה בלחיצה אחת. עם זאת, אפשר גם לשמור ערך ב-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 של תמונת הפרופיל. באפליקציות רבות, המידע הזה מספיק כדי לאמת את המשתמש בקצה העורפי וליצור חשבון חדש.

אם אתם צריכים מידע נוסף כדי להשלים את יצירת החשבון, למשל תאריך הלידה של המשתמש, אתם יכולים להציג למשתמש תהליך של פרטי הרשמה שבו אתם מבקשים את המידע הנוסף הזה. לאחר מכן, שלחו אותו לקצה העורפי כדי להשלים את יצירת החשבון.