FirebaseUI-এর মাধ্যমে আপনার iOS অ্যাপে সাইন-ইন করার সুবিধা যোগ করা

SwiftUI-এর জন্য FirebaseUI হল Firebase Authentication-এর উপরে তৈরি একটি আধুনিক, SwiftUI-ফার্স্ট লাইব্রেরি যা আপনার অ্যাপে আগে থেকে তৈরি সাইন-ইন ফ্লো প্রদান করে।

SwiftUI-এর জন্য FirebaseUI-এর নিম্নলিখিত সুবিধা রয়েছে:

  • মতামত সহ ডিফল্ট UI: AuthPickerView-এর সাথে সম্পূর্ণ সাইন-ইন ফ্লো যোগ করুন।
  • কাস্টমাইজ করা যায়: আপনার নিজস্ব লেআউটে ডিফল্ট বোতাম রেন্ডার করুন অথবা সম্পূর্ণ কাস্টম অভিজ্ঞতা তৈরি করুন।
  • পরিচয় গোপন করা অ্যাকাউন্ট লিঙ্ক করা: পরিচয় গোপন করা ব্যবহারকারীদের পরিবর্তন করার পরিবর্তে বিকল্প হিসেবে আপগ্রেড করুন।
  • অ্যাকাউন্ট ম্যানেজমেন্ট: সাইন-আপ, পাসওয়ার্ড ফিরিয়ে আনা এবং অ্যাকাউন্ট ম্যানেজমেন্টের জন্য বিল্ট-ইন ফ্লো।
  • একাধিক পরিষেবা প্রদানকারী: ইমেল/পাসওয়ার্ড, ইমেল লিঙ্ক, ফোন যাচাইকরণ, Apple, Google, Facebook, Twitter এবং স্ট্যান্ডার্ড OAuth2/OIDC পরিষেবা প্রদানকারী।
  • আধুনিক যাচাইকরণ ফিচার: বহু-স্তরীয় যাচাইকরণ (MFA) এবং async/await API-এর জন্য বিল্ট-ইন সহায়তা।

শুরু করার আগে

ইনস্টল করা

SwiftUI-এর জন্য FirebaseUI, Swift প্যাকেজ হিসেবে প্রদান করা হয়। আপনার Xcode প্রোজেক্টে প্যাকেজ ইনস্টল করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. Xcode-এ, ফাইল > প্যাকেজ ডিপেন্ডেন্সি যোগ করুন বিকল্পে ক্লিক করুন।

  2. প্যাকেজের URL লিখুন:

    https://github.com/firebase/FirebaseUI-iOS
    
  3. ডিপেন্ডেন্সি রুল মেনুতে, পরবর্তী মেজর ভার্সন পর্যন্ত বিকল্প বেছে নিন এবং সর্বনিম্ন ভার্সন লেটেস্ট রিলিজ হিসেবে সেট করুন।

  4. প্যাকেজ যোগ করুন বিকল্পে ক্লিক করুন, তারপর আপনার প্রোজেক্টে যোগ করার জন্য লাইব্রেরি বেছে নিন।

    নিম্নলিখিত লাইব্রেরি সবসময় প্রয়োজন। এতে মূল ডিপেন্ডেন্সি এবং ইমেল-পাসওয়ার্ড সাইন-ইন ও ইমেল লিঙ্ক সাইন-ইনের জন্য সহায়তা অন্তর্ভুক্ত।

    • FirebaseAuthSwiftUI

     আপনি যদি অন্য সাইন-ইন পদ্ধতি ব্যবহার করতে চান, তাহলে নিম্নলিখিত লাইব্রেরিগুলির মধ্যে থেকে এক বা একাধিক লাইব্রেরি বেছে নিন:

    • FirebaseAppleSwiftUI (Apple-এর মাধ্যমে সাইন-ইন করুন)
    • FirebaseGoogleSwiftUI (Google-এর মাধ্যমে সাইন-ইন করুন)
    • FirebaseFacebookSwiftUI (Facebook-এর মাধ্যমে সাইন-ইন করুন)
    • FirebasePhoneAuthSwiftUI (ফোন যাচাইকরণ)
    • FirebaseTwitterSwiftUI (Twitter-এর মাধ্যমে সাইন-ইন করুন)
    • FirebaseOAuthSwiftUI (GitHub, Microsoft, Yahoo-এর মতো স্ট্যান্ডার্ড OAuth এবং OIDC পরিষেবা প্রদানকারী)
  5. বেছে নেওয়া লাইব্রেরি ইনস্টল করতে প্যাকেজ যোগ করুন বিকল্পে ক্লিক করুন।

  6. আপনার টপ-লেভেলের ইনিশিয়ালাইজারে FirebaseUI-এর AuthService কনফিগার করুন View এবং এনভায়রনমেন্ট ব্যবহার করে চাইল্ড ভিউতে পরিষেবা পাস করুন।

    import FirebaseAuthSwiftUI
    import SwiftUI
    
    struct ContentView: View {
      let authService: AuthService
    
      init() {
        let configuration = AuthConfiguration()
    
        authService = AuthService(configuration: configuration)
          .withEmailSignIn() // Or whatever sign-in methods you want to support.
                             // See the next section.
      }
    
      var body: some View {
        AuthPickerView { // AuthPickerView (the prebuilt View) or a custom View.
            Text("Welcome to your app!")
        }
        .environment(authService)
      }
    }
    

সাইন-ইন পদ্ধতি সেট-আপ করা

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

ইমেল আইডি ও পাসওয়ার্ড

  1. Firebase কনসোলের সুরক্ষা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে, ইমেল/পাসওয়ার্ড প্রদানকারী চালু করুন।

  2. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
      .withEmailSignIn()
    

পাসওয়ার্ড ছাড়া ইমেল লিঙ্ক সাইন-ইন ব্যবহার করতে:

  1. Firebase কনসোলের সুরক্ষা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে, ইমেল/পাসওয়ার্ড চালু করুন, তারপর ইমেল লিঙ্ক সাইন-ইন চালু করুন। মনে রাখবেন, ইমেল লিঙ্ক সাইন-ইন ব্যবহার করতে হলে ইমেল বা পাসওয়ার্ড সাইন-ইন চালু থাকতে হবে।

  2. অনুমোদিত ডোমেন-এ লিঙ্ক ডোমেন যোগ করুন।

  3. ActionCodeSettings কনফিগার করুন, এটি AuthConfiguration-এ পাস করুন এবং প্রোভাইডার রেজিস্টার করুন:

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.url = URL(string: "https://yourapp.firebaseapp.com")
    
    guard let bundleID = Bundle.main.bundleIdentifier else {
      fatalError("Missing bundle identifier for email link authentication setup.")
    }
    actionCodeSettings.setIOSBundleID(bundleID)
    
    let configuration = AuthConfiguration(
      emailLinkSignInActionCodeSettings: actionCodeSettings
    )
    
    let authService = AuthService(configuration: configuration)
      .withEmailLinkSignIn()
    
  4. আপনি যে -এ FirebaseApp.configure() কল করেন, সেই একই AppDelegate-এ application(_:open:options:) পদ্ধতিতে লজিক যোগ করুন যা true রিটার্ন করে যখন খোলা URL একটি Firebase Authentication সাইন-ইন লিঙ্ক হয়। এই লজিক ইঙ্গিত করে যে লিঙ্কটি FirebaseUI দ্বারা পরিচালিত হয়েছিল এবং অন্যান্য লিঙ্ক হ্যান্ডলারদের দ্বারা প্রসেস করা উচিত নয়।

    import FacebookCore
    import FirebaseAuth
    import UIKit
    
    class AppDelegate: NSObject, UIApplicationDelegate {
      func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        FirebaseApp.configure()
        return true
      }
    
      func application(
        _ application: UIApplication,
        open url: URL,
        options: [UIApplication.OpenURLOptionsKey: Any] = [:]
      ) -> Bool {
        if Auth.auth().canHandle(url) {
          return true
        }
        return false
      }
    }
    
  5. আপনি কাস্টম ভিউ তৈরি করলে, লিঙ্ক আপনার অ্যাপ খুললে authService.handleSignInLink(url:) কল করুন।

Apple

Apple-এর মাধ্যমে সাইন-ইন করার সুবিধা ব্যবহার করতে:

  1. Apple-এর মাধ্যমে সাইন-ইন কনফিগার করুন:

    1. Apple-এর ডেভেলপার সাইটের সার্টিফিকেট, শনাক্তকারী ও প্রোফাইল পৃষ্ঠায় আপনার অ্যাপের জন্য 'Apple-এর মাধ্যমে সাইন-ইন করুন' ফিচার চালু করুন।
    2. ওয়েবের জন্য Apple-এর মাধ্যমে সাইন-ইন কনফিগার করুন-এর প্রথম বিভাগে যেভাবে বর্ণনা করা হয়েছে, সেইভাবে আপনার অ্যাপের সাথে ওয়েবসাইট যুক্ত করুন। প্রম্পট করা হলে, রিটার্ন URL হিসেবে নিম্নলিখিত URL রেজিস্টার করুন:
      https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
      আপনি Firebase কনসোল সেটিংস পৃষ্ঠা থেকে আপনার Firebase প্রোজেক্ট আইডি পেতে পারেন। আপনার কাজ হয়ে গেলে, নতুন পরিষেবা আইডি নোট করে নিন, যা পরের বিভাগে প্রয়োজন হবে।
    3. Apple-এর ব্যক্তিগত কী ব্যবহার করে সাইন-ইন করার সুবিধা তৈরি করুন। পরবর্তী বিভাগে আপনার নতুন ব্যক্তিগত কী এবং কী আইডি প্রয়োজন হবে।
    4. আপনি যদি Firebase Authentication-এর এমন কোনও ফিচার ব্যবহার করেন যা ব্যবহারকারীদের ইমেল পাঠায়, যার মধ্যে ইমেল লিঙ্ক সাইন-ইন, ইমেল আইডি যাচাইকরণ, অ্যাকাউন্ট পরিবর্তন বাতিল করা এবং অন্যান্য ফিচার অন্তর্ভুক্ত, তাহলে Apple-এর ব্যক্তিগত ইমেল রিলে পরিষেবা কনফিগার করুন এবং noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (অথবা আপনার কাস্টমাইজ করা ইমেল টেমপ্লেট ডোমেন) রেজিস্টার করুন যাতে Apple, Firebase Authentication-এর পাঠানো ইমেল পরিচয় গোপন রাখা Apple ইমেল আইডিতে রিলে করতে পারে।
  2. Firebase কনসোলের সুরক্ষা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে Apple চালু করুন।

    • আগের বিভাগে আপনার তৈরি করা পরিষেবা আইডি উল্লেখ করুন।
    • OAuth কোড ফ্লো কনফিগারেশন বিভাগে, আপনার Apple টিম আইডি এবং আগের বিভাগে তৈরি করা ব্যক্তিগত কী ও কী আইডি উল্লেখ করুন।
  3. Xcode-এ, প্রোজেক্ট এডিটরের সাইন-ইন ও ক্ষমতা বিভাগ খুলুন এবং Apple-এর মাধ্যমে সাইন-ইন করুন ক্ষমতা যোগ করুন।

  4. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
      .withAppleSignIn()
    

Google

Google Sign-In ব্যবহার করতে:

  1. Firebase কনসোলের নিরাপত্তা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে Google প্রদানকারী চালু করুন।

  2. আপনার প্রোজেক্টের GoogleService-Info.plist ফাইলের একটি নতুন কপি ডাউনলোড করুন এবং সেটি আপনার Xcode প্রোজেক্টে কপি করুন। আগে থেকে থাকা যেকোনও ভার্সন নতুন ভার্সন দিয়ে ওভাররাইট করুন।

  3. আপনার Xcode প্রোজেক্টে কাস্টম URL স্কিম যোগ করুন:

    1. আপনার প্রোজেক্ট কনফিগারেশন খুলুন: বাঁদিকের ট্রি ভিউতে প্রোজেক্টের নামে ক্লিক করুন। টার্গেট বিভাগ থেকে আপনার অ্যাপ বেছে নিন, তারপর তথ্য ট্যাব বেছে নিন এবং URL-এর ধরন বিভাগটি বড় করুন।

    2. + বোতামে ক্লিক করুন এবং আপনার রিভার্স করা ক্লায়েন্ট আইডির জন্য URL স্কিম যোগ করুন। এই ভ্যালু খুঁজে পেতে, GoogleService-Info.plist কনফিগারেশন ফাইল খুলুন এবং REVERSED_CLIENT_ID কী খুঁজুন। সেই 'কী'-এর ভ্যালু কপি করুন, এবং কনফিগারেশন পৃষ্ঠার URL স্কিম বক্সে এটি পেস্ট করুন। অন্যান্য ফিল্ডে কিছু করবেন না।

      সম্পূর্ণ হয়ে গেলে, আপনার কনফিগারেশন নিম্নলিখিতটির মতো দেখতে লাগবে (তবে আপনার অ্যাপ্লিকেশন-নির্দিষ্ট ভ্যালু সহ):

  4. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
      .withGoogleSignIn()
    

Facebook

Facebook Login ব্যবহার করতে:

  1. Meta for Developers সাইটে দেওয়া নির্দেশাবলী অনুসরণ করে iOS SDK-এর জন্য Facebook Login সেট-আপ করুন। শেষ ধাপ, "আপনার কোডে Facebook লগ-ইন যোগ করুন" এড়িয়ে যান।

  2. Firebase কনসোলের সুরক্ষা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে, Facebook পরিষেবা প্রদানকারী চালু করুন। Meta for Developers সাইট থেকে আপনাকে Facebook অ্যাপ আইডি ও অ্যাপ সিক্রেট নিতে হবে।

  3. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
     .withFacebookSignIn()
    

ফোন নম্বর

ফোন যাচাইকরণ ব্যবহার করতে:

  1. Firebase কনসোলের সুরক্ষা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে, ফোন প্রদানকারী চালু করুন।

  2. সাইলেন্ট বিজ্ঞপ্তি পাওয়া শুরু করুন বিভাগে দেওয়া নির্দেশাবলী অনুযায়ী আপনার অ্যাপের জন্য APN কনফিগার করুন।

  3. আপনার Xcode প্রোজেক্টে কাস্টম URL স্কিম যোগ করুন:

    1. আপনার প্রোজেক্ট কনফিগারেশন খুলুন: বাঁদিকের ট্রি ভিউতে প্রোজেক্টের নামে ক্লিক করুন। টার্গেট বিভাগ থেকে আপনার অ্যাপ বেছে নিন, তারপর তথ্য ট্যাব বেছে নিন এবং URL-এর ধরন বিভাগটি বড় করুন।

    2. + বোতামে ক্লিক করুন এবং URL স্কিম হিসেবে আপনার এনকোড করা অ্যাপ আইডি যোগ করুন। এই ভ্যালু খুঁজে পেতে, Firebase কনসোলে সেটিংস > সাধারণ বিকল্প খুলুন।

      সম্পূর্ণ হয়ে গেলে, আপনার কনফিগারেশন নিম্নলিখিতটির মতো দেখতে লাগবে (তবে আপনার অ্যাপ্লিকেশন-নির্দিষ্ট ভ্যালু সহ):

  4. আপনি যে AppDelegate-এ FirebaseApp.configure()-কে কল করেন, সেখানে APNs টোকেন হ্যান্ডলার যোগ করুন:

    import FacebookCore
    import FirebaseAuth
    import UIKit
    
    class AppDelegate: NSObject, UIApplicationDelegate {
      func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        FirebaseApp.configure()
        return true
      }
    
      func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
      ) {
        #if DEBUG
        Auth.auth().setAPNSToken(deviceToken, type: .sandbox)
        #else
        Auth.auth().setAPNSToken(deviceToken, type: .prod)
        #endif
      }
    }
    
  5. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
      .withPhoneSignIn()
    

Twitter (X)

Twitter Login ব্যবহার করতে:

  1. X Developers সাইটে দেওয়া নির্দেশাবলী অনুসরণ করে X API ক্রেডেনশিয়াল জেনারেট করুন।

  2. Firebase কনসোলের নিরাপত্তা > যাচাইকরণ > সাইন-ইন পদ্ধতি বিভাগ থেকে, Twitter প্রদানকারী চালু করুন। X Developer কনসোল থেকে আপনার API কী এবং API সিক্রেট প্রয়োজন হবে।

  3. আপনার AuthService ইনস্ট্যান্সে পরিষেবা প্রদানকারীকে রেজিস্টার করুন:

    let authService = AuthService()
      .withTwitterSignIn()
    

স্ট্যান্ডার্ড OAuth2 এবং OIDC প্রোভাইডার

এছাড়াও, FirebaseUI-তে GitHub, Microsoft ও Yahoo-এর মতো বিল্ট-ইন OAuth পরিষেবা প্রদানকারী এবং Firebase Authentication-এ কনফিগার করা কাস্টম OIDC পরিষেবা প্রদানকারী কাজ করে।

 let authService = AuthService()
  .withOAuthSignIn(OAuthProviderSwift.github())
  .withOAuthSignIn(OAuthProviderSwift.microsoft())
  .withOAuthSignIn(OAuthProviderSwift.yahoo())

কাস্টম OIDC প্রোভাইডারের জন্য, প্রথমে Firebase Authentication-এ প্রোভাইডার কনফিগার করুন, তারপর আপনার প্রোভাইডার আইডি ও বোতাম কনফিগারেশন সহ OAuthProviderSwift তৈরি করুন:

let lineProvider = OAuthProviderSwift(
  providerId: "oidc.line",
  buttonLabel: "Sign in with LINE",
  displayName: "LINE",
  iconSystemName: "person.crop.circle.badge.checkmark",
  buttonBackgroundColor: .green,
  buttonForegroundColor: .white
)

let authService = AuthService()
  .withOAuthSignIn(lineProvider)

আগে থেকে তৈরি করা যাচাইকরণ ভিউ ব্যবহার করা

SwiftUI-এর জন্য FirebaseUI AuthPickerView প্রদান করে, যা একটি আগে থেকে তৈরি, মতামতযুক্ত যাচাইকরণ UI যা আপনার জন্য সম্পূর্ণ যাচাইকরণ ফ্লো ম্যানেজ করে। আপনার অ্যাপে যাচাইকরণ যোগ করার সবচেয়ে সহজ উপায় এটি।

উদাহরণ

একাধিক পরিষেবা প্রদানকারী ও কনফিগারেশন বিকল্প সহ AuthPickerView-এর ব্যবহারের উদাহরণ এখানে দেওয়া হল:

import FirebaseAppleSwiftUI
import FirebaseAuthSwiftUI
import FirebaseGoogleSwiftUI
import SwiftUI

struct ContentView: View {
  let authService: AuthService

  init() {
    // Create configuration with options
    let configuration = AuthConfiguration(
      tosUrl: URL(string: "https://example.com/tos"),
      privacyPolicyUrl: URL(string: "https://example.com/privacy"),
      shouldAutoUpgradeAnonymousUsers: true
    )

    // Initialize AuthService with multiple providers
    authService = AuthService(configuration: configuration)
      .withEmailSignIn()
      .withAppleSignIn()
      .withGoogleSignIn()
  }

  var body: some View {
    AuthPickerView {
      authenticatedContent
    }
    .environment(authService)
  }

  var authenticatedContent: some View {
    NavigationStack {
      VStack(spacing: 20) {
        if authService.authenticationState == .authenticated {
          Text("Authenticated")
          
          Button("Manage Account") {
            authService.isPresented = true
          }
          .buttonStyle(.bordered)
          
          Button("Sign Out") {
            Task {
              try? await authService.signOut()
            }
          }
          .buttonStyle(.borderedProminent)
        } else {
          Text("Not Authenticated")
          
          Button("Sign In") {
            authService.isPresented = true
          }
          .buttonStyle(.borderedProminent)
        }
      }
      .navigationTitle("My App")
    }
    .onChange(of: authService.authenticationState) { _, newValue in
      // Automatically show auth UI when not authenticated
      if newValue != .authenticating {
        authService.isPresented = (newValue == .unauthenticated)
      }
    }
  }
}

সাধারণ কাস্টমাইজেশন

যদিও সব AuthConfiguration প্যারামিটার ঐচ্ছিক, বেশিরভাগ অ্যাপ কমপক্ষে নিম্নলিখিত সেটিংস কাস্টমাইজ করে:

let configuration = AuthConfiguration(
    logo: ImageResource.exampleLogoAsset,
    customStringsBundle: .main,
    tosUrl: URL(string: "https://example.com/tos"),
    privacyPolicyUrl: URL(string: "https://example.com/privacy"),
)
  • logo: যাচাইকরণ শিটে দেখানো লোগোর ছবি। আপনার নিজস্ব ইমেজ অ্যাসেট যোগ করার ব্যাপারে তথ্য পেতে, আপনার Xcode প্রোজেক্টে ছবি যোগ করা দেখুন।

  • customStringsBundle: নির্দিষ্ট বান্ডেল থেকে কাস্টম স্ট্রিং ব্যবহার করুন। এটি লোকালাইজেশনের জন্য ব্যবহার করা হয়, তবে AuthPickerView-এর ব্যবহার করা ডিফল্ট স্ট্রিং কাস্টমাইজ করার জন্যও ব্যবহার করা হয়। যেমন, যাচাইকরণ শিটের উপরে দেখানো মেসেজ সেট করতে, এই কন্টেন্ট সহ Localizable.strings তৈরি করুন:

    "Sign in with Firebase" = "Sign in to use ExampleApp";
    

প্রি-বিল্ট ভিউতে কী কী অন্তর্ভুক্ত আছে

AuthPickerView ব্যবহার করলে, আপনি এগুলি পাবেন:

  1. শিট প্রেজেন্টেশন: যাচাইকরণ UI একটি মডেল শিট হিসেবে দেখানো হয়
  2. বিল্ট-ইন নেভিগেশন: সাইন-ইন, পাসওয়ার্ড ফিরিয়ে আনা, MFA, ইমেল লিঙ্ক ও ফোন নম্বর যাচাইকরণ স্ক্রিনের মধ্যে অটোমেটিক নেভিগেশন
  3. যাচাইকরণ স্টেট ম্যানেজমেন্ট: authService.authenticationState-এর উপর ভিত্তি করে যাচাইকরণ UI ও আপনার কন্টেন্টের মধ্যে অটোমেটিক পাল্টায়
  4. isPresented-এর মাধ্যমে নিয়ন্ত্রণ করুন: authService.isPresented = true/false সেট করার মাধ্যমে কখন যাচাইকরণ শিট দেখানো হবে তা নিয়ন্ত্রণ করুন

মতামত ভিত্তিক আচরণ

ডিফল্ট AuthPickerView-এ একাধিক জটিল পরিস্থিতি কীভাবে সামলাতে হবে সেই সম্পর্কে মতামত দেওয়া আছে:

১. অ্যাকাউন্ট সংক্রান্ত সমস্যার সমাধান

অ্যাকাউন্ট সংক্রান্ত কোনও সমস্যা হলে (যেমন, অন্য অ্যাকাউন্টের সাথে আগে থেকেই লিঙ্ক করা ক্রেডেনশিয়াল দিয়ে সাইন-ইন করা), AuthPickerView অটোমেটিক তা ম্যানেজ করে:

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

এটি NavigationStack লেভেলে প্রয়োগ করা AccountConflictModifier দ্বারা ম্যানেজ করা হয়।

২. বহু-স্তরীয় যাচাইকরণ (MFA)

আপনার কনফিগারেশনে MFA চালু করা থাকলে:

  • সাইন-ইন করার সময় MFA-এর প্রয়োজন হলে অটোমেটিক শনাক্ত করে
  • উপযুক্ত MFA রেজোলিউশন স্ক্রিন (SMS বা TOTP) দেখায়
  • MFA এনরোলমেন্ট ও ম্যানেজমেন্ট ফ্লো হ্যান্ডেল করে
  • এসএমএস-ভিত্তিক এবং সময়-ভিত্তিক একবার ব্যবহারের পাসওয়ার্ড (TOTP) ফ্যাক্টর, দুটিতেই কাজ করে
৩. সমস্যা ম্যানেজ করা

ডিফল্ট ভিউতে বিল্ট-ইন সমস্যা সমাধান করার সুবিধা অন্তর্ভুক্ত থাকে:

  • সতর্কতা ডায়ালগে ব্যবহার করা সহজ এমন ত্রুটি মেসেজ দেখায়
  • অভ্যন্তরীণভাবে ম্যানেজ করা সমস্যাগুলি অটোমেটিক ফিল্টার করে (যেমন, বাতিলকরণ সংক্রান্ত সমস্যা, অটোমেটিক ম্যানেজ করা দ্বন্দ্ব)
  • StringUtils-এর মাধ্যমে স্থানীয় ভাষায় সমস্যার মেসেজ ব্যবহার করে
  • reportError এনভায়রনমেন্ট কী-এর মাধ্যমে সমস্যাগুলি প্রোপাগেট করা হয়

ইমেল লিঙ্ক সাইন-ইন কনফিগার করা থাকলে:

  • অ্যাপ স্টোরেজে ইমেল আইডি অটোমেটিক স্টোর করে
  • ইমেল থেকে ডিপ লিঙ্ক নেভিগেশন ম্যানেজ করে
  • ইমেল যাচাইকরণের সম্পূর্ণ ফ্লো ম্যানেজ করে
  • ইমেল লিঙ্কের মাধ্যমে পরিচয় গোপন করা ব্যবহারকারীর আপগ্রেড করার সুবিধা দেয়
৫. পরিচয় গোপন করা ব্যবহারকারীর অটো-আপগ্রেড

shouldAutoUpgradeAnonymousUsers চালু করা থাকলে:

  • নতুন সাইন-ইন ক্রেডেনশিয়ালের সাথে পরিচয় গোপন রাখা অ্যাকাউন্ট অটোমেটিক লিঙ্ক করার চেষ্টা করে
  • পরিচয় গোপন রাখা সেশন পরিবর্তন করার পরিবর্তে আপগ্রেড করার মাধ্যমে ব্যবহারকারীর ডেটা সুরক্ষিত রাখে
  • আপগ্রেড সংক্রান্ত বিরোধ সুন্দরভাবে ম্যানেজ করে
৬. ডিফল্ট ভিউতে আবার যাচাই করা

অ্যাকাউন্ট মুছে ফেলা, পাসওয়ার্ড আপডেট করা বা MFA ফ্যাক্টর থেকে নাম সরিয়ে নেওয়ার মতো সংবেদনশীল অপারেশন করার জন্য সাম্প্রতিক যাচাইকরণ প্রয়োজন। ডিফল্ট ভিউ ব্যবহার করার সময়, ব্যবহারকারীর সাইন-ইন প্রদানকারীর উপর ভিত্তি করে আবার যাচাই করার প্রসেস অটোমেটিক ম্যানেজ করা হয়।

কোনও সংবেদনশীল অপারেশনের জন্য আবার যাচাইকরণের প্রয়োজন হলে, ডিফল্ট ভিউ অটোমেটিক:

  • OAuth পরিষেবা প্রদানকারী (Google, Apple, Facebook, Twitter ইত্যাদি): ব্যবহারকারীকে কনফার্ম করতে বলে একটি সতর্কতা দেখান, তারপর অটোমেটিক নতুন ক্রেডেনশিয়াল পান এবং অপারেশন সম্পূর্ণ করুন।

  • ইমেল/পাসওয়ার্ড: ব্যবহারকারীকে তার পাসওয়ার্ড লিখতে প্রম্পট করে এমন একটি শিট দেখান।

  • ইমেল লিঙ্ক: যাচাইকরণ ইমেল পাঠানোর জন্য অনুরোধ করে একটি সতর্কতা দেখান, তারপর ইমেল চেক করার নির্দেশাবলী সহ একটি শিট দেখান। আবার যাচাইকরণ সম্পূর্ণ করতে ব্যবহারকারী তার ইমেলে থাকা লিঙ্কে ট্যাপ করেন।

  • ফোন: যাচাইকরণ প্রয়োজন তা ব্যাখ্যা করে একটি সতর্কতা দেখান, তারপর এসএমএস কোড যাচাইকরণের জন্য একটি শিট দেখান।

আবার যাচাইকরণ সম্পূর্ণ হওয়ার পরে অপারেশন অটোমেটিক আবার চেষ্টা করে। AuthPickerView বা বিল্ট-ইন অ্যাকাউন্ট ম্যানেজমেন্ট ভিউ (UpdatePasswordView, SignedInView ইত্যাদি) ব্যবহার করার সময় কোনও অতিরিক্ত কোডের প্রয়োজন হয় না।

উন্নত: কাস্টম যাচাইকরণ ভিউ তৈরি করা

UI বা নেভিগেশন ফ্লোর উপর আপনার আরও নিয়ন্ত্রণ প্রয়োজন হলে, আপনি নিজের কাস্টম যাচাইকরণ ভিউ তৈরি করতে পারেন, তবে যাচাইকরণ লজিকের জন্য AuthService ব্যবহার করতে পারেন।

আপনি বিভিন্ন উপায়ে কাস্টম লজিকের সাথে FirebaseUI-এর এলিমেন্ট মিক্স করতে পারবেন। নিম্নলিখিত বিভাগে কিছু কাস্টমাইজেশন পদ্ধতির উদাহরণ রয়েছে যা আপনি ব্যবহার করতে পারেন।

পদ্ধতি ১: registerProvider() সহ কাস্টম বোতাম

বোতামের চেহারার উপর সম্পূর্ণ নিয়ন্ত্রণ পেতে, আপনি নিজের কাস্টম AuthProviderUI প্রয়োগ তৈরি করতে পারেন যা যেকোনও প্রদানকারীকে র‍্যাপ করে এবং আপনার কাস্টম বোতাম ভিউ ফিরিয়ে দেয়।

কাস্টম প্রোভাইডার UI তৈরি করা

উদাহরণ হিসেবে, কাস্টম Twitter বোতাম কীভাবে তৈরি করবেন তা এখানে দেওয়া হল:

import FirebaseAuthSwiftUI
import FirebaseTwitterSwiftUI
import SwiftUI

// Step 1: Create your custom button view
struct CustomTwitterButton: View {
  let provider: TwitterProviderSwift
  @Environment(AuthService.self) private var authService
  @Environment(\.mfaHandler) private var mfaHandler

  var body: some View {
    Button {
      Task {
        do {
          let outcome = try await authService.signIn(provider)

          // Handle MFA if required
          if case let .mfaRequired(mfaInfo) = outcome,
             let onMFA = mfaHandler {
            onMFA(mfaInfo)
          }
        } catch {
          // Do Something Else
        }
      }
    } label: {
      HStack { // Your custom icon
        Text("Sign in with Twitter")
          .fontWeight(.semibold)
      }
      .frame(maxWidth: .infinity)
      .padding()
      .background(
        LinearGradient(
          colors: [Color.blue, Color.cyan],
          startPoint: .leading,
          endPoint: .trailing
        )
      )
      .foregroundColor(.white)
      .cornerRadius(12)
      .shadow(radius: 4)
    }
  }
}

// Step 2: Create a custom AuthProviderUI wrapper
class CustomTwitterProviderAuthUI: AuthProviderUI {
  private let typedProvider: TwitterProviderSwift
  var provider: AuthProviderSwift { typedProvider }
  let id: String = "twitter.com"

  init(provider: TwitterProviderSwift = TwitterProviderSwift()) {
    typedProvider = provider
  }

  @MainActor func authButton() -> AnyView {
    AnyView(CustomTwitterButton(provider: typedProvider))
  }
}

// Step 3: Use it in your app
struct ContentView: View {
  let authService: AuthService

  init() {
    let configuration = AuthConfiguration()
    authService = AuthService(configuration: configuration)

    // Register your custom provider UI
    authService.registerProvider(
      providerWithButton: CustomTwitterProviderAuthUI()
    )
    authService.isPresented = true
  }

  var body: some View {
    AuthPickerView {
      usersApp
    }
    .environment(authService)
  }

  var usersApp: some View {
    NavigationStack {
      VStack {
        Button {
          authService.isPresented = true
        } label: {
          Text("Authenticate")
        }
      }
    }
  }
}

সহজ কাস্টম বোতামের উদাহরণ

এছাড়াও, আপনি যেকোনও পরিষেবা প্রদানকারীর জন্য আরও সহজ কাস্টম বোতাম তৈরি করতে পারবেন:

import FirebaseAuthSwiftUI
import FirebaseGoogleSwiftUI
import FirebaseAppleSwiftUI
import SwiftUI

// Custom Google Provider UI
class CustomGoogleProviderAuthUI: AuthProviderUI {
  private let typedProvider: GoogleProviderSwift
  var provider: AuthProviderSwift { typedProvider }
  let id: String = "google.com"
  
  init() {
    typedProvider = GoogleProviderSwift()
  }
  
  @MainActor func authButton() -> AnyView {
    AnyView(CustomGoogleButton(provider: typedProvider))
  }
}

struct CustomGoogleButton: View {
  let provider: GoogleProviderSwift
  @Environment(AuthService.self) private var authService
  
  var body: some View {
    Button {
      Task {
        try? await authService.signIn(provider)
      }
    } label: {
      HStack {
        Image(systemName: "g.circle.fill")
        Text("My Custom Google Button")
      }
      .frame(maxWidth: .infinity)
      .padding()
      .background(Color.purple) // Your custom color
      .foregroundColor(.white)
      .cornerRadius(10)
    }
  }
}

// Then use it
struct ContentView: View {
  let authService: AuthService
  
  init() {
    let configuration = AuthConfiguration()
    authService = AuthService(configuration: configuration)
      .withAppleSignIn() // Use default Apple button
    
    // Use custom Google button
    authService.registerProvider(
      providerWithButton: CustomGoogleProviderAuthUI()
    )
  }
  
  var body: some View {
    AuthPickerView {
      Text("App Content")
    }
    .environment(authService)
  }
}

এই পদ্ধতি সব পরিষেবা প্রদানকারীর ক্ষেত্রে কাজ করে: Google, Apple, Twitter, Facebook, ফোন ও OAuth পরিষেবা প্রদানকারী। আপনার কাস্টম বোতাম ভিউ তৈরি করুন এবং AuthProviderUI-এর সাথে মানানসই ক্লাসে এটি র‍্যাপ করুন।

পদ্ধতি ২: কাস্টম ভিউ সহ ডিফল্ট বোতাম

আপনার নিজস্ব লেআউট এবং নেভিগেশন প্রদান করার সময় ডিফল্ট যাচাইকরণ বোতাম রেন্ডার করতে আপনি AuthService.renderButtons() ব্যবহার করতে এবং AuthPickerView বাইপাস করতে পারেন:

import FirebaseAuthSwiftUI
import FirebaseGoogleSwiftUI
import FirebaseAppleSwiftUI
import SwiftUI

struct CustomAuthView: View {
  @Environment(AuthService.self) private var authService

  var body: some View {
    VStack(spacing: 30) {
      // Your custom logo/branding
      Image("app-logo")
        .resizable()
        .frame(width: 150, height: 150)
      
      Text("Welcome to My App")
        .font(.largeTitle)
        .fontWeight(.bold)
      
      Text("Sign in to continue")
        .font(.subheadline)
        .foregroundStyle(.secondary)
      
      // Render default auth buttons
      authService.renderButtons(spacing: 12)
        .padding()
    }
    .padding()
  }
}

struct ContentView: View {
  init() {
    let configuration = AuthConfiguration()
    
    authService = AuthService(configuration: configuration)
      .withGoogleSignIn()
      .withAppleSignIn()
  }
  
  let authService: AuthService

  var body: some View {
    NavigationStack {
      if authService.authenticationState == .authenticated {
        Text("Authenticated!")
      } else {
        CustomAuthView()
      }
    }
    .environment(authService)
  }
}

পদ্ধতি ৩: কাস্টম নেভিগেশন সহ কাস্টম ভিউ

পুরো ফ্লোয়ের উপর সম্পূর্ণ নিয়ন্ত্রণ পেতে, আপনি AuthPickerView বাইপাস করে নিজের নেভিগেশন সিস্টেম তৈরি করতে পারেন:

import FirebaseAuth
import FirebaseAuthSwiftUI
import FirebaseGoogleSwiftUI
import SwiftUI

enum CustomAuthRoute {
  case signIn
  case phoneVerification
  case mfaResolution
}

struct ContentView: View {
  private let authService: AuthService
  @State private var navigationPath: [CustomAuthRoute] = []
  @State private var errorMessage: String?

  init() {
    let configuration = AuthConfiguration()
    self.authService = AuthService(configuration: configuration)
      .withGoogleSignIn()
      .withPhoneSignIn()
  }

  var body: some View {
    NavigationStack(path: $navigationPath) {
      Group {
        if authService.authenticationState == .authenticated {
          authenticatedView
        } else {
          customSignInView
        }
      }
      .navigationDestination(for: CustomAuthRoute.self) { route in
        switch route {
        case .signIn:
          customSignInView
        case .phoneVerification:
          customPhoneVerificationView
        case .mfaResolution:
          customMFAView
        }
      }
    }
    .environment(authService)
    .alert("Error", isPresented: .constant(errorMessage != nil)) {
      Button("OK") {
        errorMessage = nil
      }
    } message: {
      Text(errorMessage ?? "")
    }
  }

  var customSignInView: some View {
    VStack(spacing: 20) {
      Text("Custom Sign In")
        .font(.title)
      
      Button("Sign in with Google") {
        Task {
          do {
            let provider = GoogleProviderSwift(clientID: Auth.auth().app?.options.clientID ?? "")
            let outcome = try await authService.signIn(provider)
            
            // Handle MFA if required
            if case .mfaRequired = outcome {
              navigationPath.append(.mfaResolution)
            }
          } catch {
            errorMessage = error.localizedDescription
          }
        }
      }
      .buttonStyle(.borderedProminent)
      
      Button("Phone Sign In") {
        navigationPath.append(.phoneVerification)
      }
      .buttonStyle(.bordered)
    }
    .padding()
  }

  var customPhoneVerificationView: some View {
    Text("Custom Phone Verification View")
    // Implement your custom phone auth UI here
  }

  var customMFAView: some View {
    Text("Custom MFA Resolution View")
    // Implement your custom MFA UI here
  }

  var authenticatedView: some View {
    VStack(spacing: 20) {
      Text("Welcome!")
      Text("Email: \(authService.currentUser?.email ?? "N/A")")
      
      Button("Sign Out") {
        Task {
          try? await authService.signOut()
        }
      }
      .buttonStyle(.borderedProminent)
    }
  }
}

কাস্টম ভিউয়ের জন্য গুরুত্বপূর্ণ বিবেচনা

কাস্টম ভিউ তৈরি করার সময়, আপনাকে নিজে থেকে বেশ কিছু জিনিস ম্যানেজ করতে হবে যা AuthPickerView অটোমেটিক ম্যানেজ করে:

  1. অ্যাকাউন্ট সংক্রান্ত বিরোধ: AuthServiceError.accountConflict ব্যবহার করে বিরোধ সমাধানের নিজস্ব স্ট্র্যাটেজি প্রয়োগ করুন
  2. MFA ম্যানেজ করা: .mfaRequired-এর জন্য SignInOutcome চেক করুন এবং ম্যানুয়ালি MFA রেজোলিউশন ম্যানেজ করুন
  3. বেনামী ব্যবহারকারীর আপগ্রেড: shouldAutoUpgradeAnonymousUsers চালু থাকলে বেনামী অ্যাকাউন্টের লিঙ্কিং ম্যানেজ করুন
  4. নেভিগেশন স্টেট: বিভিন্ন যাচাইকরণ স্ক্রিনের (ফোন নম্বর যাচাইকরণ, পাসওয়ার্ড ফিরিয়ে আনা ইত্যাদি) মধ্যে নেভিগেশন ম্যানেজ করুন
  5. লোডিং স্টেট: authService.authenticationState পর্যবেক্ষণ করে অ্যাসিঙ্ক যাচাইকরণ অপারেশন চলাকালীন লোডিং ইন্ডিকেটর দেখান
  6. আবার যাচাই করা: সংবেদনশীল অপারেশনের জন্য আবার যাচাই করার সময় হওয়া সমস্যা ম্যানেজ করা (নিচে কাস্টম ভিউতে আবার যাচাই করা দেখুন)

কাস্টম ভিউতে আবার যাচাই করা

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

প্রয়োগের প্যাটার্ন

OAuth পরিষেবা প্রদানকারী (Google, Apple, Facebook, Twitter, ইত্যাদি):

সমস্যাটি খুঁজে বের করুন এবং reauthenticate(context:) কল করুন যা অটোমেটিক OAuth ফ্লো ম্যানেজ করে:

do {
  try await authService.deleteUser()
} catch let error as AuthServiceError {
  if case .oauthReauthenticationRequired(let context) = error {
    try await authService.reauthenticate(context: context)
    try await authService.deleteUser() // Retry operation
  }
}

ইমেল/পাসওয়ার্ড:

সমস্যাটি ধরুন, পাসওয়ার্ডের জন্য প্রম্পট করুন, ক্রেডেনশিয়াল তৈরি করুন এবং reauthenticate(with:)-এ কল করুন:

do {
  try await authService.updatePassword(to: newPassword)
} catch let error as AuthServiceError {
  if case .emailReauthenticationRequired(let context) = error {
    // Show your password prompt UI
    let password = await promptUserForPassword()
    let credential = EmailAuthProvider.credential(
      withEmail: context.email,
      password: password
    )
    try await authService.reauthenticate(with: credential)
    try await authService.updatePassword(to: newPassword) // Retry
  }
}

ফোন:

সমস্যাটি খুঁজে বের করুন, ফোন নম্বর যাচাই করুন, ক্রেডেনশিয়াল তৈরি করুন এবং reauthenticate(with:)-এ কল করুন:

do {
  try await authService.deleteUser()
} catch let error as AuthServiceError {
  if case .phoneReauthenticationRequired(let context) = error {
    // Send verification code
    let verificationId = try await authService.verifyPhoneNumber(
      phoneNumber: context.phoneNumber
    )
    // Show your SMS code input UI
    let code = await promptUserForSMSCode()
    let credential = PhoneAuthProvider.provider().credential(
      withVerificationID: verificationId,
      verificationCode: code
    )
    try await authService.reauthenticate(with: credential)
    try await authService.deleteUser() // Retry
  }
}

ইমেল লিঙ্ক:

সমস্যাটি ধরুন, যাচাইকরণ ইমেল পাঠান এবং ইনকামিং URL ম্যানেজ করুন:

do {
  try await authService.updatePassword(to: newPassword)
} catch let error as AuthServiceError {
  if case .emailLinkReauthenticationRequired(let context) = error {
    // Send verification email
    try await authService.sendEmailSignInLink(
      email: context.email,
      isReauth: true
    )
    // Show your "Check your email" UI
    await showCheckEmailUI()
    // When user taps the link, it opens your app with a URL
    // Handle it in your URL handler:
    // try await authService.handleSignInLink(url: url)
    // The handleSignInLink method automatically completes reauthentication
    try await authService.updatePassword(to: newPassword) // Retry
  }
}

সব রি-অথেন্টিকেশন কনটেক্সট অবজেক্টে ব্যবহারকারী নিজে ইন্টার‌্যাক্ট করতে পারেন এমন টেক্সটের জন্য একটি .displayMessage প্রপার্টি থাকে।

কাস্টম OAuth পরিষেবা প্রদানকারী

আপনি বিল্ট-ইন পরিষেবা ছাড়াও অন্যান্য পরিষেবার জন্য কাস্টম OAuth পরিষেবা প্রদানকারী তৈরি করতে পারেন:

⚠️ গুরুত্বপূর্ণ: OIDC (OpenID Connect) পরিষেবা প্রদানকারীকে ব্যবহার করার আগে আপনার Firebase প্রোজেক্টের Authentication সেটিংসে কনফিগার করতে হবে। Firebase কনসোলে, যাচাইকরণ → সাইন-ইন পদ্ধতি বিকল্পে যান এবং প্রয়োজনীয় ক্রেডেনশিয়াল (ক্লায়েন্ট আইডি, ক্লায়েন্ট সিক্রেট, ইস্যুকারীর URL) সহ আপনার OIDC প্রদানকারী যোগ করুন। এছাড়াও, আপনাকে অবশ্যই আপনার পরিষেবা প্রদানকারীর ডেভেলপার কনসোলে Firebase-এর প্রদান করা OAuth রিডাইরেক্ট URI রেজিস্টার করতে হবে। সেট-আপের বিস্তারিত নির্দেশাবলীর জন্য Firebase OIDC ডকুমেন্টেশন দেখুন।

import FirebaseAuthSwiftUI
import FirebaseOAuthSwiftUI
import SwiftUI

struct ContentView: View {
  let authService: AuthService

  init() {
    let configuration = AuthConfiguration()
    
    authService = AuthService(configuration: configuration)
      .withOAuthSignIn(
        OAuthProviderSwift(
          providerId: "oidc.line",  // LINE OIDC provider
          scopes: ["profile", "openid", "email"],  // LINE requires these scopes
          displayName: "Sign in with LINE",
          buttonIcon: Image("line-logo"),
          buttonBackgroundColor: .green,
          buttonForegroundColor: .white
        )
      )
      .withOAuthSignIn(
        OAuthProviderSwift(
          providerId: "oidc.custom-provider",
          scopes: ["profile", "openid"],
          displayName: "Sign in with Custom",
          buttonIcon: Image(systemName: "person.circle"),
          buttonBackgroundColor: .purple,
          buttonForegroundColor: .white
        )
      )
  }

  var body: some View {
    AuthPickerView {
      Text("App Content")
    }
    .environment(authService)
  }
}