[英]Organizing groups in Firebase Authentication on Swift
我在 Xcode 中的 Swift 上使用 Firebase 身份驗證。 我想為用戶登錄創建“組”,以便某些用戶可以訪問某些數據。 例如,在我的應用程序中,我希望籃球隊中的籃球運動員只能訪問籃球統計數據。 有誰知道這在 Firebase 中叫什么以及怎么做?
如前所述,身份驗證用戶(Auth user)只是身份驗證用戶,它不包含更多信息。 請參閱 Firebase(身份驗證)的隨附屏幕截圖:
這就是為什么我們必須添加一個新的User結構(在users集合中),它提供所有這些類型的信息(可能是姓名、年齡、某些東西的組......等等)。 用戶文檔需要對 Auth 用戶的引用。 在示例中,我使用的是用戶 uid(@frank-van-puffelen 是使用 uid 的常用方法還是會導致安全相關問題?)
附帶說明一下,由於我們只獲取整個文檔,並且有時用戶可能擁有一些對其他人不可用的私有數據,因此將結構拆分為 PublicUser 和 PrivateUser 可能是有意義的。
無論如何,對於這個例子,讓我們在 swift 中創建一個用戶結構
//
// User.swift
// Firebase User
//
// Created by Sebastian Fox on 18.08.22.
//
import Foundation
import SwiftUI
import Firebase
struct User: Codable, Identifiable, Hashable {
var id: String?
var name: String
var group: SportType
init(name: String, group: SportType, id: String?) {
self.id = id
self.name = name
self.group = group
}
init?(document: QueryDocumentSnapshot) {
let data = document.data()
guard let name = data["name"] as? String else {
return nil
}
guard let group = data["group"] as? SportType else {
return nil
}
id = document.documentID
self.name = name
self.group = group
}
enum CodingKeys: String, CodingKey {
case id
case name
case group
}
}
extension User: Comparable {
static func == (lhs: User, rhs: User) -> Bool {
return lhs.id == rhs.id
}
static func < (lhs: User, rhs: User) -> Bool {
return lhs.name < rhs.name
}
}
// I also create an enum with sort types, this is not necessarily part of the User struct. To load it to the Firestone database it must be codable.
enum SportType: String, Codable, CaseIterable {
case basektball = "Basketball"
case baseball = "Baseball"
case soccer = "Soccer"
case chess = "Chess"
case noSport = "No Sport"
}
現在,讓我們用 UserViewModel 來做魔術,它包含我們調用的函數來使用 Firebase (Firestore),例如 signUp(這里我們談論的是 Auth 用戶)、signIn(再次驗證用戶)或 createNewUser(這里是我們的新用戶)用戶結構):
//
// UserViewModel.swift
// Firebase User
//
// Created by Sebastian Fox on 18.08.22.
//
import Foundation
import FirebaseFirestore
import Firebase
import FirebaseFirestoreSwift
class UsersViewModel: ObservableObject {
let db = Firestore.firestore()
// Published and saved to local device
@Published var users = [User]()
// Sign Up
func signUp(email: String, password: String, completion: @escaping (Bool, String)->Void) {
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
// ERROR AND SUCCESS HANDLING
if error != nil {
// ERROR HANDLING
print(error?.localizedDescription as Any)
completion(false, "ERROR")
}
// SUCCESS HANDLING
completion(true, authResult?.user.uid ?? "")
}
}
// Sign In
func signIn(email: String, password: String, completion: @escaping (Bool)->Void) {
Auth.auth().signIn(withEmail: email, password: password) { (authResult, error) in
// ERROR AND SUCCESS HANDLING
if error != nil {
// ERROR HANDLING
print(error?.localizedDescription as Any)
completion(true)
}
// SUCCESS HANDLING
completion(true)
}
}
// Sign Out
func signOut() {
try! Auth.auth().signOut()
}
// Create new user
func createNewUser(name: String, group: SportType, id: String) {
do {
let newUser = User(name: name, group: group, id: id)
try db.collection("users").document(newUser.id!).setData(from: newUser) { _ in
print("User \(name) created")
}
} catch let error {
print("Error writing user to Firestore: \(error)")
}
}
// FOR TESTING: Get a list of all users
func fetchAllUsers(_ completion: @escaping (Bool) ->Void) {
self.users = []
db.collection("users").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.users = documents.map { queryDocumentSnapshot -> User in
let data = queryDocumentSnapshot.data()
let id = data["id"] as? String ?? ""
let name = data["name"] as? String ?? ""
let group = data["group"] as? String ?? ""
return User(name: name, group: SportType(rawValue: group) ?? .noSport, id: id)
}
completion(true)
}
}
}
現在您有 2 個選項來注冊(身份驗證用戶)並創建一個新用戶(基於新用戶結構):
您有 2 個單獨的視圖,在第一個視圖上,用戶注冊,創建 Auth 用戶。 在第二個視圖中,僅在注冊后可用,用戶可以添加名稱、組或任何您想要的數據。 (我更喜歡這個選項)
您可以在一個視圖中處理所有事情。 您持有所有必要的數據,調用注冊 function 並在收到完成響應時調用 function 來創建用戶。
最后一件事,由於您無法從 Auth.auth() 中獲取該信息,因此如果您希望能夠更改這些數據,則必須從 Firestore 數據庫中獲取該特定用戶的用戶數據。 當然,您可以在創建新用戶時將這些信息作為值保存到 UserDefaults(存儲),稍后您可以在用戶登錄時保存該信息。
最好的,塞巴斯蒂安
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.