এক ট্যাপ দিয়ে নতুন অ্যাকাউন্ট তৈরি করুন

আপনি যদি গুগল অ্যাকাউন্ট দিয়ে সাইন ইন করা সমর্থন করেন, তাহলে ওয়ান ট্যাপ সাইন-ইন ক্লায়েন্ট ব্যবহার করে আপনার ব্যবহারকারীদের একটি নির্বিঘ্ন অ্যাকাউন্ট তৈরির অভিজ্ঞতাও দিতে পারেন, যা তাদেরকে আপনার অ্যাপের পরিধি থেকে কখনোই বের করে আনে না।

এক-ট্যাপ সাইন-আপ UI

যখন আপনি ওয়ান ট্যাপ UI প্রদর্শন করেন, তখন ব্যবহারকারীদের তাদের ডিভাইসে থাকা গুগল অ্যাকাউন্টগুলোর মধ্যে একটি ব্যবহার করে আপনার অ্যাপে একটি নতুন অ্যাকাউন্ট তৈরি করার জন্য অনুরোধ করা হয়। যদি ব্যবহারকারী এগিয়ে যেতে চান, তাহলে আপনি মৌলিক প্রোফাইল তথ্যসহ একটি আইডি টোকেন পাবেন—যেমন তাদের নাম, প্রোফাইল ফটো এবং তাদের যাচাইকৃত ইমেল ঠিকানা—যা আপনি নতুন অ্যাকাউন্টটি তৈরি করতে ব্যবহার করতে পারেন।

ওয়ান ট্যাপ অ্যাকাউন্ট তৈরির বাস্তবায়নের দুটি অংশ রয়েছে:

  • আপনার অ্যাপে ওয়ান ট্যাপ ক্লায়েন্টকে একীভূত করার পদ্ধতি এই পৃষ্ঠায় বর্ণনা করা হয়েছে। এটি মূলত ওয়ান ট্যাপ সাইন-ইন ব্যবহারের মতোই, তবে কনফিগারেশনে কিছু পার্থক্য রয়েছে।
  • আপনার ব্যাকএন্ডে গুগল আইডি টোকেন থেকে ব্যবহারকারী অ্যাকাউন্ট তৈরি করার ক্ষমতা যোগ করা, যা "ব্যাকএন্ডে আইডি টোকেন ব্যবহার করা" অংশে আলোচনা করা হয়েছে।

আমি ওয়ান ট্যাপ সাইন-আপ কোথায় ব্যবহার করব?

ব্যবহারকারীদের ওয়ান ট্যাপ সাইন-আপ অফার করার সবচেয়ে কার্যকর জায়গা হলো এমন পরিস্থিতি, যেখানে সাইন ইন করলে নতুন ফিচার চালু হবে। প্রথমে, সংরক্ষিত ক্রেডেনশিয়াল দিয়ে ব্যবহারকারীকে সাইন ইন করানোর চেষ্টা করুন। যদি কোনো সংরক্ষিত ক্রেডেনশিয়াল খুঁজে না পাওয়া যায়, তবে ব্যবহারকারীর জন্য একটি নতুন অ্যাকাউন্ট তৈরি করার প্রস্তাব দিন।

শুরু করার আগে

"ওয়ান ট্যাপ সাইন-ইন দিয়ে শুরু করুন" অংশে বর্ণিত পদ্ধতি অনুযায়ী আপনার গুগল এপিআই কনসোল প্রজেক্ট এবং অ্যান্ড্রয়েড প্রজেক্ট সেট আপ করুন।

১. ওয়ান ট্যাপ ক্লায়েন্ট কনফিগার করুন

অ্যাকাউন্ট তৈরির জন্য ওয়ান ট্যাপ ক্লায়েন্ট কনফিগার করতে, নিম্নলিখিতগুলি করুন:

  • পাসওয়ার্ডের মাধ্যমে পরিচয়পত্র চাওয়ার অনুরোধ চালু করবেন না। (শুধুমাত্র টোকেন-ভিত্তিক প্রমাণীকরণের মাধ্যমেই এক-ট্যাপে সাইন-আপ করা সম্ভব।)
  • 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()
        // ...
    }
    // ...
}

২. ওয়ান ট্যাপ UI বাতিলকরণের উপর নজর রাখুন

ব্যবহারকারী প্রম্পটটি বন্ধ করে বা এর বাইরে ট্যাপ করে ওয়ান ট্যাপ সাইন-আপ ব্যবহার করতে ইতোমধ্যেই অস্বীকৃতি জানিয়েছেন কিনা, তার হিসাব আপনার রাখা উচিত। এটি আপনার অ্যাক্টিভিটির একটি বুলিয়ান প্রপার্টির মতোই সহজ হতে পারে। (নিচে ‘ওয়ান ট্যাপ UI প্রদর্শন বন্ধ করুন’ দেখুন।)

৩. ওয়ান ট্যাপ সাইন-আপ UI প্রদর্শন করুন।

যদি ব্যবহারকারী ওয়ান ট্যাপ ব্যবহার করে নতুন অ্যাকাউন্ট তৈরি করতে অস্বীকৃতি না জানিয়ে থাকেন, তাহলে ক্লায়েন্ট অবজেক্টের beginSignIn() মেথডটি কল করুন এবং এর থেকে প্রাপ্ত Task টিতে লিসেনার সংযুক্ত করুন। অ্যাপগুলো সাধারণত এই ধাপটি অনুসরণ করে যখন কোনো ওয়ান ট্যাপ সাইন-ইন অনুরোধে সংরক্ষিত কোনো ক্রেডেনশিয়াল খুঁজে পাওয়া যায় না—অর্থাৎ, সাইন -ইন অনুরোধের ফেইলর লিসেনারে।

ডিভাইসে ব্যবহারকারীর এক বা একাধিক গুগল অ্যাকাউন্ট সেট আপ করা থাকলে ওয়ান ট্যাপ ক্লায়েন্ট সাকসেস লিসেনারকে কল করবে। সাকসেস লিসেনারে, Task রেজাল্ট থেকে পেন্ডিং ইন্টেন্টটি নিন এবং ওয়ান ট্যাপ UI শুরু করার জন্য এটিকে startIntentSenderForResult() -এ পাস করুন।

যদি ব্যবহারকারীর ডিভাইসে কোনো গুগল অ্যাকাউন্ট না থাকে, তাহলে ওয়ান ট্যাপ ক্লায়েন্ট ফেইলর লিসেনারকে কল করবে। এক্ষেত্রে কোনো পদক্ষেপ নেওয়ার প্রয়োজন নেই: আপনি কেবল অ্যাপটির সাইন-আউট করা অভিজ্ঞতা দেখানো চালিয়ে যেতে পারেন, এবং ব্যবহারকারী আপনার স্বাভাবিক অ্যাকাউন্ট তৈরির প্রক্রিয়া অনুসরণ করে সাইন আপ করতে পারবেন।

জাভা

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

৪. ব্যবহারকারীর প্রতিক্রিয়া পরিচালনা করুন

ওয়ান ট্যাপ সাইন-আপ প্রম্পটে ব্যবহারকারীর প্রতিক্রিয়া আপনার অ্যাক্টিভিটির onActivityResult() মেথড ব্যবহার করে আপনার অ্যাপে জানানো হবে। যদি ব্যবহারকারী একটি অ্যাকাউন্ট তৈরি করতে চান, তাহলে ফলাফলটি একটি গুগল আইডি টোকেন হবে। যদি ব্যবহারকারী ওয়ান ট্যাপ UI বন্ধ করে বা এর বাইরে ট্যাপ করে সাইন আপ করতে অস্বীকার করেন, তাহলে ফলাফলটি RESULT_CANCELED কোডসহ ফেরত আসবে। আপনার অ্যাপকে এই উভয় পরিস্থিতিই সামাল দিতে হবে।

গুগল আইডি টোকেন দিয়ে একটি অ্যাকাউন্ট তৈরি করুন

যদি ব্যবহারকারী একটি গুগল অ্যাকাউন্ট দিয়ে সাইন আপ করার সিদ্ধান্ত নেন, তাহলে আপনি onActivityResult() থেকে ইন্টেন্ট ডেটা One Tap ক্লায়েন্টের getSignInCredentialFromIntent() মেথডে পাস করে ব্যবহারকারীর জন্য একটি আইডি টোকেন পেতে পারেন। ক্রেডেনশিয়ালটিতে একটি নন-নাল 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) {
                    // ...
            }
        }
    }
    // ...
}

ওয়ান ট্যাপ UI প্রদর্শন বন্ধ করুন

যদি ব্যবহারকারী সাইন ইন করতে অস্বীকার করেন, তাহলে getSignInCredentialFromIntent() কলটি CommonStatusCodes.CANCELED স্ট্যাটাস কোড সহ একটি ApiException থ্রো করবে। যখন এমনটা ঘটে, তখন আপনার সাময়িকভাবে ওয়ান ট্যাপ সাইন-ইন UI প্রদর্শন বন্ধ করা উচিত, যাতে বারবার প্রম্পট করে ব্যবহারকারীদের বিরক্ত না করা হয়। নিম্নলিখিত উদাহরণটি অ্যাক্টিভিটিতে একটি প্রপার্টি সেট করার মাধ্যমে এটি সম্পন্ন করে, যা ব্যবহারকারীকে ওয়ান ট্যাপ সাইন-ইন অফার করা হবে কিনা তা নির্ধারণ করতে ব্যবহৃত হয়; তবে, আপনি SharedPreferences এ একটি মান সংরক্ষণ করতে বা অন্য কোনো পদ্ধতিও ব্যবহার করতে পারেন।

ওয়ান ট্যাপ সাইন-ইন প্রম্পটের জন্য আপনার নিজস্ব রেট লিমিটিং প্রয়োগ করা জরুরি। যদি আপনি তা না করেন এবং কোনো ব্যবহারকারী পরপর বেশ কয়েকটি প্রম্পট বাতিল করে দেন, তাহলে ওয়ান ট্যাপ ক্লায়েন্ট পরবর্তী ২৪ ঘণ্টার জন্য তাকে আর কোনো প্রম্পট দেখাবে না।

জাভা

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

পরবর্তী পদক্ষেপ

যখন কোনো ব্যবহারকারী ওয়ান ট্যাপ সাইন-আপ প্রক্রিয়াটি সম্পন্ন করেন, তখন আপনি একটি গুগল আইডি টোকেন পান, যাতে কিছু প্রাথমিক প্রোফাইল তথ্য থাকে: ব্যবহারকারীর ইমেল ঠিকানা, পুরো নাম এবং প্রোফাইল পিকচারের ইউআরএল। অনেক অ্যাপের ক্ষেত্রে, ব্যাকএন্ডে ব্যবহারকারীকে প্রমাণীকরণ করতে এবং একটি নতুন অ্যাকাউন্ট তৈরি করার জন্য এই তথ্যই যথেষ্ট।

অ্যাকাউন্ট তৈরি সম্পন্ন করার জন্য যদি আপনার অতিরিক্ত তথ্যের প্রয়োজন হয়—উদাহরণস্বরূপ, ব্যবহারকারীর জন্ম তারিখ—তবে ব্যবহারকারীকে একটি সাইন-আপ বিবরণ প্রক্রিয়া দেখান, যেখানে আপনি এই অতিরিক্ত তথ্যটি চাইবেন। তারপর, অ্যাকাউন্ট তৈরি সম্পন্ন করার জন্য সেই তথ্য আপনার ব্যাকএন্ডে পাঠিয়ে দিন।