
FirebaseUI برای SwiftUI یک کتابخانه مدرن و SwiftUI-اول است که در بالای Firebase Authentication ساخته شده است و جریانهای ورود به سیستم ازپیش ساختهشده را برای برنامه شما فراهم میکند.
FirebaseUI برای SwiftUI مزایای زیر را دارد:
- میانای کاربر پیشفرض با نظر شخصی: جریان ورود به سیستم کامل را با
AuthPickerViewاضافه کنید. - قابلسفارشیسازی: دکمههای پیشفرض را در چیدمان خودتان ارائه دهید یا تجربه کاملاً سفارشی بسازید.
- پیونددهی حساب ناشناس: بهصورت اختیاری کاربران ناشناس را بهجای جایگزین کردن آنها ارتقا دهید.
- مدیریت حساب: گردشهای کاری داخلی برای ثبتنام، بازیابی گذرواژه، و مدیریت حساب.
- ارائهدهندگان متعدد: ایمیل/گذرواژه، پیوند ایمیل، اصالتسنجی تلفنی، Apple، Google، Facebook، Twitter، و ارائهدهندگان استاندارد OAuth2/OIDC.
- ویژگیهای اصالتسنجی مدرن: پشتیبانی داخلی از اصالتسنجی چندعاملی (MFA) و APIهای ناهمزمان/انتظار.
قبل از شروع
Firebase را به پروژه Apple خود اضافه کنید. حتماً مراحل SwiftUI را تکمیل کنید.
مطمئن شوید برنامه شما iOS 17 یا جدیدتر را هدف قرار میدهد.
نصب
FirebaseUI برای SwiftUI بهعنوان بسته Swift ارائه میشود. برای نصب بسته در پروژه Xcode خود، مراحل زیر را انجام دهید:
در Xcode، روی File > Add Package Dependencies (فایل > افزودن وابستگیهای بسته) کلیک کنید.
نشانی وب بسته را وارد کنید:
https://github.com/firebase/FirebaseUI-iOSدر منو قانون وابستگی، تا نسخه اصلی بعدی را انتخاب کنید و حداقل نسخه را روی جدیدترین نسخه تنظیم کنید.
روی افزودن بسته کلیک کنید، سپس کتابخانههایی را که میخواهید به پروژهتان اضافه کنید انتخاب کنید.
کتابخانه زیر همیشه الزامی است. این کتابخانه شامل وابستگیهای اصلی و همچنین پشتیبانی از ورود به سیستم با ایمیل-گذرواژه و ورود به سیستم با پیوند ایمیل است.
FirebaseAuthSwiftUI
اگر میخواهید از روشهای ورود به سیستم دیگر پشتیبانی کنید، یک یا چند کتابخانه از کتابخانههای زیر را نیز انتخاب کنید:
-
FirebaseAppleSwiftUI(ورود به سیستم با Apple) -
FirebaseGoogleSwiftUI(ورود به سیستم با Google) -
FirebaseFacebookSwiftUI(ورود به سیستم با Facebook) -
FirebasePhoneAuthSwiftUI(اصالتسنجی تلفنی) -
FirebaseTwitterSwiftUI(ورود به سیستم با X) FirebaseOAuthSwiftUI(ارائهدهندگان استاندارد OAuth و OIDC مانند GitHub، Microsoft، Yahoo)
برای نصب کتابخانههای انتخابشده، روی افزودن بسته کلیک کنید.
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) } }
راهاندازی روشهای ورود به سیستم
هریک از روشهای ورود به سیستم پشتیبانیشده به چند مرحله راهاندازی اضافی نیاز دارند. بخشهای زیر را ازهم باز کنید و دستورالعملها را برای راهاندازی ارائهدهندگان تکی دنبال کنید.
نشانی ایمیل و گذرواژه
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ارائهدهنده ایمیل/گذرواژه را فعال کنید.
ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withEmailSignIn()
اصالتسنجی پیوند ایمیل
برای استفاده از ورود به سیستم با پیوند ایمیل بدون گذرواژه:
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ایمیل/گذرواژه را فعال کنید، سپس ورود به سیستم با پیوند ایمیل را فعال کنید. توجه داشته باشید که برای استفاده از ورود به سیستم با پیوند ایمیل، باید ورود به سیستم با ایمیل یا گذرواژه فعال باشد.
دامنه پیوند را به دامنههای مجاز اضافه کنید.
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()در همان
AppDelegateکهFirebaseApp.configure()را فراخوانی میکنید، منطق را به روشapplication(_:open:options:)اضافه کنید کهtrueرا وقتی نشانی وب بازشده پیوند ورود به سیستم 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 } }اگر نماهای سفارشی میسازید، وقتی پیوند برنامهتان را باز میکند،
authService.handleSignInLink(url:)را فراخوانی کنید.
Apple
برای استفاده از «ورود به سیستم با Apple»:
پیکربندی «ورود به سیستم با Apple»:
- «ورود به سیستم با Apple» را برای برنامهتان در صفحه گواهینامهها، شناسهها، و نمایهها سایت توسعهدهندگان Apple فعال کنید.
- وبسایتتان را همانطور که در بخش اول پیکربندی «ورود به سیستم با Apple» برای وب توضیح داده شده است با برنامهتان مرتبط کنید. وقتی پیامواره نشان داده شد، نشانی وب زیر را بهعنوان «نشانی وب برگشتی» ثبت کنید:
میتوانید شناسه پروژه Firebase خود را در Firebaseصفحه تنظیمات کنسول دریافت کنید. وقتی کارتان تمام شد، «شناسه سرویس» جدیدتان را یادداشت کنید، زیرا در بخش بعدی به آن نیاز خواهید داشت.https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
- ایجاد کلید خصوصی «ورود به سیستم با Apple». در بخش بعدی به کلید خصوصی و شناسه کلید جدیدتان نیاز خواهید داشت.
- اگر از هریک از ویژگیهای Firebase Authentication که ایمیل به کاربران ارسال میکند استفاده میکنید،
ازجمله ورود به سیستم با پیوند ایمیل، درستیسنجی نشانی ایمیل، لغو تغییر حساب،
و موارد دیگر، سرویس رله ایمیل خصوصی Apple را پیکربندی کنید
و
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com(یا دامنه الگوی ایمیل سفارشیسازیشده خودتان) را ثبت کنید تا Apple بتواند ایمیلهای ارسالی از Firebase Authentication به نشانیهای ایمیل ناشناس Apple را رله کند.
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، Apple را فعال کنید.
- «شناسه سرویس» را که در بخش قبلی ایجاد کردهاید مشخص کنید.
- در بخش پیکربندی جریان کد OAuth، «شناسه تیم Apple» و کلید خصوصی و شناسه کلیدی را که در بخش قبلی ایجاد کردید مشخص کنید.
در Xcode، بخش امضا و قابلیتها را در ویرایشگر پروژه باز کنید و قابلیت ورود به سیستم با Apple را اضافه کنید.
ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withAppleSignIn()
برای استفاده از «ورود به سیستم با Google»:
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ارائهدهنده Google را فعال کنید.
نسخه جدیدی از فایل
GoogleService-Info.plistپروژه خود را بارگیری کنید و آن را در پروژه Xcode خود کپی کنید. هر نسخه موجود را با نسخه جدید رونویسی کنید.طرحهای نشانی وب سفارشی را به پروژه Xcode خود اضافه کنید:
پیکربندی پروژه را باز کنید: روی نام پروژه در نمای درختی سمت راست کلیک کنید. برنامه خود را از بخش هدفها انتخاب کنید، سپس برگه اطلاعات را انتخاب کنید و بخش انواع نشانی وب را ازهم باز کنید.
روی دکمه + کلیک کنید و طرح نشانی وب را برای شناسه مشتری معکوس خود اضافه کنید. برای پیدا کردن این مقدار، فایل پیکربندی
را باز کنید و کلیدGoogleService-Info.plist REVERSED_CLIENT_IDرا پیدا کنید. مقدار آن کلید را کپی کنید و آن را در کادر طرحهای نشانی وب در صفحه پیکربندی جایگذاری کنید. فیلدهای دیگر را دست نزنید.وقتی تکمیل شد، پیکربندی شما باید چیزی شبیه به موارد زیر باشد (اما با مقادیر خاص برنامه شما):

ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withGoogleSignIn()
فیسبوک
برای استفاده از «ورود به سیستم Facebook»:
«ورود به سیستم Facebook» را برای «کیت توسعه نرمافزار iOS» با دنبال کردن دستورالعملها در سایت Meta for Developers راهاندازی کنید. از مرحله نهایی، «افزودن ورود به سیستم Facebook به کد خود»، صرفنظر کنید.
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ارائهدهنده Facebook را فعال کنید. به «شناسه برنامه Facebook» و «رمز برنامه» از سایت Meta for Developers نیاز خواهید داشت.
ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withFacebookSignIn()
شماره تلفن
برای استفاده از اصالتسنجی تلفنی:
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ارائهدهنده تلفن را فعال کنید.
«نامهای نقطه دسترسی» را برای برنامهتان طبق دستورالعملهای بخش شروع دریافت اعلانهای بیصدا پیکربندی کنید.
طرحهای نشانی وب سفارشی را به پروژه Xcode خود اضافه کنید:
پیکربندی پروژه را باز کنید: روی نام پروژه در نمای درختی سمت راست کلیک کنید. برنامه خود را از بخش هدفها انتخاب کنید، سپس برگه اطلاعات را انتخاب کنید و بخش انواع نشانی وب را ازهم باز کنید.
روی دکمه + کلیک کنید و «شناسه برنامه کدبندیشده» خود را بهعنوان طرح نشانی وب اضافه کنید. برای پیدا کردن این مقدار، تنظیمات > کلی را در کنسول Firebase باز کنید.
وقتی تکمیل شد، پیکربندی شما باید چیزی شبیه به موارد زیر باشد (اما با مقادیر خاص برنامه شما):

در همان
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 } }ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withPhoneSignIn()
توییتر (X)
برای استفاده از «ورود به سیستم X»:
با دنبال کردن دستورالعملها در سایت «توسعهدهندگان X»، اطلاعات اعتباری «میانای برنامهسازی کاربردی X» را تولید کنید.
از بخش امنیت > اصالتسنجی > روش ورود به سیستم در کنسول Firebase، ارائهدهنده X را فعال کنید. به کلید میانای برنامهسازی کاربردی و رمز میانای برنامهسازی کاربردی از X Developer Console نیاز خواهید داشت.
ارائهدهنده را در نمونه
AuthServiceخود ثبت کنید:let authService = AuthService() .withTwitterSignIn()
ارائهدهندگان استاندارد OAuth2 و OIDC
FirebaseUI همچنین از ارائهدهندگان OAuth داخلی مانند GitHub، Microsoft، و Yahoo و همچنین ارائهدهندگان OIDC سفارشی که در «احراز هویت Firebase» پیکربندی شدهاند پشتیبانی میکند.
let authService = AuthService()
.withOAuthSignIn(OAuthProviderSwift.github())
.withOAuthSignIn(OAuthProviderSwift.microsoft())
.withOAuthSignIn(OAuthProviderSwift.yahoo())
برای ارائهدهندگان OIDC سفارشی، ابتدا ارائهدهنده را در «احراز هویت Firebase» پیکربندی کنید، سپس 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)
استفاده از نمای اصالتسنجی ازپیش ساختهشده
FirebaseUI برای SwiftUI AuthPickerView را ارائه میدهد، یک واسط کاربر اصالتسنجی ازپیش ساختهشده و نظردهنده که کل جریان اصالتسنجی را برای شما مدیریت میکند. این
آسانترین راه برای افزودن اصالتسنجی به برنامه است.
مثال
در اینجا نمونهای از 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 استفاده میکنید، این موارد را دریافت میکنید:
- ارائه برگ: میانای کاربری اصالتسنجی بهصورت برگ مُدال ظاهر میشود
- پیمایش داخلی: پیمایش خودکار بین صفحههای ورود به سیستم، بازیابی گذرواژه، «احراز هویت چندعاملی»، پیوند ایمیل، و درستیسنجی تلفن
- مدیریت وضعیت اصالتسنجی: براساس
authService.authenticationState، بهطور خودکار بین میانای کاربر اصالتسنجی و محتوای شما جابهجا میشود - کنترل ازطریق
isPresented: با تنظیمauthService.isPresented = true/false، کنترل کنید برگه مجوز چه زمانی ظاهر شود
رفتارهای نظرپردازانه
AuthPickerView پیشفرض درباره نحوه مدیریت چندین سناریو پیچیده
نظر دارد:
۱. حل تعارض حساب
وقتی تعارض حساب رخ میدهد (برای نمونه، ورود به سیستم با اطلاعات اعتباری که قبلاً به حساب دیگری پیوند شده است)، AuthPickerView بهطور خودکار آن را مدیریت میکند:
- تعارضهای ارتقای ناشناس: اگر
shouldAutoUpgradeAnonymousUsersفعال باشد و تعارضی درطول ارتقای ناشناس رخ دهد، سیستم بهطور خودکار کاربر ناشناس را از سیستم خارج میکند و با اطلاعات اعتباری جدید به سیستم وارد میشود. - تعارضهای دیگر: برای تعارضهای اطلاعات اعتباری بین حسابهای غیرناشناس، سیستم اطلاعات اعتباری معلقه را ذخیره میکند و پساز ورود موفقیتآمیز به سیستم، تلاش میکند آن را پیوند دهد.
این کار توسط AccountConflictModifier اعمالشده در سطح NavigationStack انجام میشود.
۲. اصالتسنجی چندعاملی (MFA)
وقتی «احراز هویت چندعاملی» در پیکربندی شما فعال باشد:
- هنگام ورود به سیستم، بهطور خودکار تشخیص میدهد که آیا به «احراز هویت چندعاملی» نیاز است یا نه
- صفحههای مناسب برای حل مشکل «احراز هویت چندعاملی» (پیامک یا TOTP) را ارائه میدهد
- جریانهای ثبتنام و مدیریت «احراز هویت چندعاملی» را مدیریت میکند
- از عوامل گذرواژه یکبارمصرف مبتنی بر پیامک و مبتنی بر زمان (TOTP) پشتیبانی میکند
۳. مدیریت خطا
نماهای پیشفرض شامل مدیریت خطای داخلی است:
- پیامهای خطای کاربرپسند را در کادرهای گفتگوی هشدار نمایش میدهد
- خطاهایی را که بهصورت داخلی مدیریت میشوند (برای نمونه، خطاهای لغو، تداخلهای مدیریتشده خودکار) بهطور خودکار فیلتر میکند
- ازطریق
StringUtilsاز پیامهای خطای بومیسازیشده استفاده میکند - خطاها ازطریق کلید محیط
reportErrorمنتشر میشوند
۴. ورود به سیستم با پیوند ایمیل
وقتی ورود به سیستم با پیوند ایمیل پیکربندی شده باشد:
- نشانی ایمیل را بهطور خودکار در فضای ذخیرهسازی برنامه ذخیره میکند
- پیمایش پیوند عمیق را از ایمیل مدیریت میکند
- گردش کامل درستیسنجی ایمیل را مدیریت میکند
- از ارتقاهای کاربر ناشناس ازطریق پیوند ایمیل پشتیبانی میکند
۵. ارتقای خودکار کاربر ناشناس
وقتی shouldAutoUpgradeAnonymousUsers فعال باشد:
- بهطور خودکار تلاش میکند حسابهای ناشناس را با اطلاعات اعتباری ورود به سیستم جدید پیوند دهد
- با ارتقا دادن بهجای جایگزین کردن جلسههای ناشناس، دادههای کاربر را حفظ میکند
- تداخلهای ارتقا را بهخوبی مدیریت میکند
۶. احراز هویت مجدد در نماهای پیشفرض
عملیات حساس مثل حذف حسابها، بهروزرسانی گذرواژهها، یا لغو ثبت عوامل «اصالتسنجی چندعاملی» نیاز به اصالتسنجی اخیر دارند. هنگام استفاده از نماهای پیشفرض، اصالتسنجی مجدد بهطور خودکار براساس ارائهدهنده ورود به سیستم کاربر انجام میشود.
وقتی عملیات حساسی نیاز به اصالتسنجی مجدد دارد، نماهای پیشفرض بهطور خودکار:
ارائهدهندگان OAuth (Google، Apple، Facebook، Twitter، و غیره): هشدار تأییدیهای به کاربر نمایش دهید، سپس بهطور خودکار اطلاعات اعتباری جدید را دریافت کنید و عملیات را تکمیل کنید.
ایمیل/گذرواژه: برگهای را ارائه دهید که از کاربر میخواهد قبلاز ادامه دادن، گذرواژه خود را وارد کند.
پیوند ایمیل: هشداری نشان داده میشود که از کاربر میخواهد ایمیل درستیسنجی ارسال کند، سپس برگهای با دستورالعملهای بررسی ایمیل ارائه میشود. کاربر روی پیوند موجود در ایمیل خود ضربه میزند تا اصالتسنجی مجدد را تکمیل کند.
تلفن: هشداری نشان دهید که توضیح دهد درستیسنجی لازم است، سپس برگهای برای درستیسنجی کد پیامکی ارائه دهید.
پساز اصالتسنجی مجدد موفقیتآمیز، عملیات بهطور خودکار دوباره امتحان میشود. هنگام استفاده از AuthPickerView یا نماهای مدیریت حساب داخلی (UpdatePasswordView، SignedInView، و غیره)، به کد اضافی نیاز نیست.
پیشرفته: ساختن نماهای سفارشی اصالتسنجی
اگر به کنترل بیشتری روی رابط کاربری یا جریان پیمایش نیاز دارید، میتوانید نماهای اصالتسنجی سفارشی خودتان را بسازید و درعینحال از AuthService برای منطق اصالتسنجی استفاده کنید.
به روشهای مختلفی میتوانید عناصر FirebaseUI را با منطق سفارشی ترکیب کنید. بخشهای زیر شامل نمونههایی از برخیاز رویکردهای سفارشیسازی است که میتوانید استفاده کنید.
رویکرد ۱: دکمههای سفارشی با registerProvider()
برای کنترل کامل ظاهر دکمه، میتوانید پیادهسازی سفارشی AuthProviderUI خودتان را ایجاد کنید که هر ارائهدهندهای را دربرمیگیرد و نمای دکمه سفارشی شما را برمیگرداند.
ایجاد کردن واسط کاربر ارائهدهنده سفارشی
در اینجا نحوه ایجاد یک دکمه سفارشی 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، Phone، و ارائهدهندگان 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 بهطور خودکار مدیریت میکند، خودتان مدیریت کنید:
- تعارضهای حساب: بااستفاده از
AuthServiceError.accountConflict، استراتژی حل تعارض خودتان را پیادهسازی کنید - مدیریت MFA:
SignInOutcomeرا برای.mfaRequiredبررسی کنید و حل MFA را بهصورت دستی انجام دهید - ارتقاهای کاربر ناشناس: اگر
shouldAutoUpgradeAnonymousUsersفعال باشد، پیوند حسابهای ناشناس را مدیریت کنید - وضعیت پیمایش: مدیریت پیمایش بین صفحههای اصالتسنجی مختلف (درستیسنجی تلفن، بازیابی گذرواژه، و غیره)
- حالتهای بار کردن: با مشاهده
authService.authenticationState، نشانگرهای بار کردن را درطول عملیات اصالتسنجی ناهمزمان نشان دهید - احراز هویت مجدد: مدیریت خطاهای احراز هویت مجدد برای عملیات حساس (به احراز هویت مجدد در «نماهای سفارشی» در زیر مراجعه کنید)
احراز هویت مجدد در نماهای سفارشی
هنگام ساختن نماهای سفارشی، با دریافت خطاهای خاص و پیادهسازی جریان خودتان، اصالتسنجی مجدد را مدیریت کنید. عملیات حساس چهار نوع خطای اصالتسنجی مجدد ایجاد میکنند که هرکدام حاوی اطلاعات زمینهای هستند.
الگوهای پیادهسازی
ارائهدهندگان 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) باید در تنظیمات «احراز هویت» پروژه Firebase شما پیکربندی شوند تا بتوان از آنها استفاده کرد. در «کنسول Firebase»، به اصالتسنجی → روش ورود به سیستم بروید و ارائهدهنده OIDC خود را با اعتبارنامههای موردنیاز (شناسه کارخواه، رمز کارخواه، نشانی وب صادرکننده) اضافه کنید. همچنین باید نشانی وب هدایت OAuth ارائهشده توسط Firebase را در کنسول توسعهدهنده ارائهدهنده خود ثبت کنید. برای دستورالعملهای دقیق راهاندازی، مستندات 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)
}
}