- Published on
Firebase Firestore'da foydalanuvchi profilini yaratish (user profiles)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Auth va Firestore: Farqi nima?
Ko'pchilik yangi o'rganayotgan dasturchilar bitta narsada adashadi: Firebase Authentication bu faqatgina odamni tanib olish (autentifikatsiya) uchun xizmat qiladi. U yerdan biz faqatgina uid (User ID), email va xavfsizlik tokenlarini olamiz xolos. Ammo foydalanuvchining ilova ichidagi ma'lumotlari (masalan: Ismi nima? U qaysi davlatdan? Premium obunasi bormi?) kabi narsalarni u yerda saqlab bo'lmaydi. Bu ma'lumotlarni biz o'zimizning Firestore ma'lumotlar bazamizdagi "Foydalanuvchilar" (Users) kolleksiyasida saqlashimiz kerak.
Shuning uchun to'g'ri oqim (flow) har doim shunday bo'ladi:
- Foydalanuvchi ilovaga kiradi (Auth orqali).
- Tizim unga yangi o'zgarmas
uid(User ID) beradi. - Biz shu zahoti Firestore'ga kirib,
usersdegan kolleksiya ochamiz va aynan o'shauidnomli User Profile hujjatini yaratib qo'yamiz. - Keyin ilovaning qolgan joylarida faqat o'sha Firestore'dagi hujjat ustida ishlaymiz.
1-qadam: Kutubxonalarni o'rnatish
Agar xotirangizda bo'lsa, loyiha boshida biz faqat FirebaseAuth paketini o'rnatgan edik. Endi bizga Firestore kerak.
- Xcode'da loyiha sozlamalaridan
Package Dependenciesbo'limiga kiring. - Firebase paketini tanlang.
- Ro'yxatdan
FirebaseFirestorevaFirebaseFirestoreSwift(bu async/await va Codable uchun muhim) paketlarini belgilab loyihaga qo'shing.
2-qadam: UserManager klassi
Oldingi darslarda AuthenticationManager ochganimiz kabi, endi Firestore bilan ishlash uchun UserManager degan alohida menejer klassini yaratamiz:
import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift
final class UserManager {
// Singleton (yagona nusxa) pattern
static let shared = UserManager()
private init() {}
// Firestore'ga kirish uchun yo'l
private let userCollection = Firestore.firestore().collection("users")
}
3-qadam: Hujjat yaratish (Write)
Endi yangi foydalanuvchi profilini yaratadigan funksiyani yozamiz. Biz ma'lumotlarni baza tushunadigan Dictionary [String: Any] shaklida beramiz. Bu yerda hujjat ID'si sifatida document() ichiga ataylab Firebase Auth bergan uid ni kiritamiz (avtomatik ID yaratilmasligi uchun):
func createNewUser(authData: AuthDataResultModel) async throws {
// 1. Bazaga yozish uchun ma'lumotlarni tayyorlash
var userData: [String: Any] = [
"user_id": authData.uid,
"is_anonymous": authData.isAnonymous,
"date_created": Timestamp() // Firebase'ning maxsus sana formati
]
if let email = authData.email {
userData["email"] = email
}
// 2. Ma'lumotni bazaga jo'natish (setData)
try await userCollection.document(authData.uid).setData(userData, merge: false)
}
Nega merge: false? Chunki biz yangi hujjat yaratyapmiz va uni noldan yozishimiz kerak. merge: true esa bor hujjatning ustiga faqat ma'lum joylarini yangilash (update) uchun ishlatiladi.
Endi buni AuthenticationManager dan foydalanuvchi ro'yxatdan o'tgan zahotiyoq chaqirib qo'yishni unutmang!
4-qadam: Hujjatni o'qib olish (Read)
Bazada profil paydo bo'ldi. Dasturni yopib qayta ochganda bu ma'lumotlarni qanday qilib Swift kodi ichiga qaytarib olamiz? Buning uchun avval Swift Data Modelini (Struct) tuzib olamiz:
struct DBUser {
let userId: String
let isAnonymous: Bool?
let email: String?
let dateCreated: Date?
}
Va UserManager ichiga getUser funksiyasini yozamiz. Unda .getDocument() orqali ma'lumotni tortib olib, har bir fieldni o'z qo'limiz bilan bittalab ajratib olamiz:
func getUser(userId: String) async throws -> DBUser {
// 1. Hujjatni Snapshot ko'rinishida tortib olish
let snapshot = try await userCollection.document(userId).getDocument()
// 2. Snapshot ichidan Dictionary ma'lumotni olish
guard let data = snapshot.data() else {
throw URLError(.badServerResponse)
}
// 3. Dictionary'dan kerakli maydonlarni bittalab ajratib olish (Parsing)
let uid = data["user_id"] as? String ?? ""
let isAnonymous = data["is_anonymous"] as? Bool
let email = data["email"] as? String
// Timestamp'ni Swift Date'iga o'girish
let dateCreated = (data["date_created"] as? Timestamp)?.dateValue()
// 4. Swift obyektini qaytarish
return DBUser(
userId: uid,
isAnonymous: isAnonymous,
email: email,
dateCreated: dateCreated
)
}
Xulosa
Bizning kodimiz juda yaxshi ishlayapti, ammo tasavvur qiling, profilingizda 50 xil maydon (Ism, Yosh, Rasmlar array'i, Manzil va hokazo) bo'lsa... Ularni data["key"] as? Type shaklida bittalab yozib chiqish qanchalik mashaqqatli va xato qilish ehtimoli yuqori! Nastarin kelajak! Keyingi darsda biz Swift'ning ajoyib imkoniyati — Codable dan foydalanib, bu amallarni avtomatlashtirishni (qo'lda yozmaslikni) o'rganamiz. Bu sizning yuzlab qator kodingizni qisqartirib beradi!