You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发:Firebase管理器类是否应使用静态成员?探讨编程设计

嘿,我看你正在打造一个集成Firebase多功能的项目,还想到用统一管理器来简化重复操作,这个思路超棒!把分散在各个视图控制器里的Firebase操作封装起来,确实能大幅减少冗余代码,提升项目的可维护性。

下面是完善后的Firebase管理器实现方案,结合单例模式和模块化封装,帮你搞定认证、数据库、存储的统一操作:

Firebase 统一管理器实现
import Foundation
import Firebase

class FirebaseManager {
    // 全局唯一实例,单例模式核心
    static let shared = FirebaseManager()
    
    // 实时获取当前登录用户UID,无需手动维护
    var currentUID: String? {
        return Auth.auth().currentUser?.uid
    }
    
    // Firebase核心服务引用,初始化后全局可用
    let databaseRootRef: DatabaseReference
    let storageRootRef: StorageReference
    let authentication: Auth
    
    // 私有初始化,确保只能通过shared获取实例
    private init() {
        // 初始化Firebase核心(如果没在AppDelegate/SceneDelegate做过的话)
        FirebaseApp.configure()
        
        self.authentication = Auth.auth()
        self.databaseRootRef = Database.database().reference()
        self.storageRootRef = Storage.storage().reference()
    }
    
    // MARK: - 认证模块
    /// 邮箱密码登录
    func signIn(withEmail email: String, password: String, completion: @escaping (Result<User, Error>) -> Void) {
        authentication.signIn(withEmail: email, password: password) { authResult, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            guard let user = authResult?.user else {
                completion(.failure(NSError(domain: "FirebaseManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户信息获取失败"])))
                return
            }
            completion(.success(user))
        }
    }
    
    /// 邮箱密码注册
    func signUp(withEmail email: String, password: String, completion: @escaping (Result<User, Error>) -> Void) {
        authentication.createUser(withEmail: email, password: password) { authResult, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            guard let user = authResult?.user else {
                completion(.failure(NSError(domain: "FirebaseManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户信息获取失败"])))
                return
            }
            completion(.success(user))
        }
    }
    
    // MARK: - 数据库模块
    /// 向指定路径上传数据
    func uploadData(to path: String, data: [String: Any], completion: @escaping (Error?) -> Void) {
        databaseRootRef.child(path).setValue(data) { error, _ in
            completion(error)
        }
    }
    
    /// 从指定路径获取单条数据
    func downloadData(from path: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
        databaseRootRef.child(path).observeSingleEvent(of: .value) { snapshot in
            guard let data = snapshot.value as? [String: Any] else {
                completion(.failure(NSError(domain: "FirebaseManager", code: -2, userInfo: [NSLocalizedDescriptionKey: "数据格式不匹配"])))
                return
            }
            completion(.success(data))
        } withCancel: { error in
            completion(.failure(error))
        }
    }
    
    // MARK: - 存储模块
    /// 上传本地文件到Firebase Storage
    func uploadFile(to path: String, fileURL: URL, completion: @escaping (Result<URL, Error>) -> Void) {
        let targetRef = storageRootRef.child(path)
        let uploadTask = targetRef.putFile(from: fileURL)
        
        uploadTask.observe(.success) { _ in
            targetRef.downloadURL { url, error in
                if let error = error {
                    completion(.failure(error))
                    return
                }
                guard let downloadURL = url else {
                    completion(.failure(NSError(domain: "FirebaseManager", code: -3, userInfo: [NSLocalizedDescriptionKey: "下载链接获取失败"])))
                    return
                }
                completion(.success(downloadURL))
            }
        }
        
        uploadTask.observe(.failure) { snapshot in
            if let error = snapshot.error {
                completion(.failure(error))
            }
        }
    }
}

核心设计说明

  • 单例模式:通过static let shared创建全局唯一实例,私有初始化方法避免外部重复创建,确保Firebase服务只初始化一次。
  • 自动维护用户UID:用计算属性currentUID实时获取当前登录用户ID,不用手动存储和更新。
  • 模块化封装:把认证、数据库、存储的操作拆分成独立方法,每个方法只负责一件事,回调用Result类型让逻辑更清晰。
  • 全局复用引用:初始化时就创建好数据库、存储、认证的核心引用,不用在每个视图控制器里重复创建。

使用示例

在任意视图控制器里直接调用即可,再也不用重复写Firebase初始化代码:

// 登录示例
FirebaseManager.shared.signIn(withEmail: "test@example.com", password: "123456") { result in
    switch result {
    case .success(let user):
        print("登录成功,用户UID:\(user.uid)")
    case .failure(let error):
        print("登录失败:\(error.localizedDescription)")
    }
}

// 上传用户数据到数据库示例
guard let uid = FirebaseManager.shared.currentUID else { return }
let userData = ["nickname": "小明", "avatarURL": "xxx"]
FirebaseManager.shared.uploadData(to: "users/\(uid)", data: userData) { error in
    if let error = error {
        print("数据上传失败:\(error.localizedDescription)")
    } else {
        print("数据上传成功")
    }
}

内容的提问来源于stack exchange,提问作者Ryan Jin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:28