为整个应用程序引用一个类的单个实例(Firebase)

Posted

技术标签:

【中文标题】为整个应用程序引用一个类的单个实例(Firebase)【英文标题】:Referencing a single instance of a class for entire application (Firebase) 【发布时间】:2020-11-11 19:46:42 【问题描述】:

我使用 Firebase 作为我的后端,当用户注册时,我会在我的 Firestore 数据库中创建一个新文档,然后在该文档上启动一个侦听器。当用户退出时,出于安全原因,我希望能够停止收听。 我目前有一个标准的 Session 侦听器类来处理 Firebase 身份验证并检测用户何时登录/注销:

会话监听器

class SessionListener : ObservableObject 
@Published var session: User?  didSet  self.didChange.send(self) 

var carRepo: CarRepository = CarRepository()
var didChange = PassthroughSubject<SessionListener, Never>()
var handle: AuthStateDidChangeListenerHandle?
    
func listen () 
    // monitor authentication changes using firebase
    handle = Auth.auth().addStateDidChangeListener  (auth, user) in
        if let user = user 
            // if we have a user, create a new user model
            self.session = User(uid: user.uid,name,email: user.email)
            self.carRepo.initialiseUser()
         else 
            // if we don't have a user, set our session to nil
            self.session = nil
        
    

...
//Sign in / Sign up methods below

我还有一个存储库类来与我的 Firestore 数据库通信(设置侦听器等)

汽车存储库

class CarRepository: ObservableObject 

let db = Firestore.firestore()
@Published var cars = [Car]()
@Published var listener: ListenerRegistration?

init()
    loadData()


func detatchListener()
    if(self.listener != nil) 
        self.listener!.remove()
    

    
func loadData()         
    if(Auth.auth().currentUser?.uid != nil)
        self.listener = db.collection("users").document(Auth.auth().currentUser!.uid).collection("cars").addSnapshotListener  (querySnapshot, error) in
        if let querySnapshot = querySnapshot 
            querySnapshot.documents.compactMap  document in  
                try? self.cars.append(document.data(as: Car.self)!)
            
        
        
    

...
//Add user to DB below

我的问题是我需要从两个 SessionListener 访问这个 CarRepository(检测用户何时注销以便我可以调用 detachListener(),我还需要访问 CarRepository 在 vi​​ewModel 中解析汽车数组。 问题是这会创建两个单独的 CarRepository 实例(正在为同一个文档设置多个侦听器,并且只有 SessionListener 创建的实例才会具有 detachListener() 调用。相反,我希望有一个所有类/结构都可以访问的对象。

【问题讨论】:

【参考方案1】:

有一个用于数据库交互的单例管理器类。在该类中,您可以拥有[String: CarRepository] 类型的属性。 String 键是文档的路径。这样你可以保证每条路径只有 1 个对象。

每当您想到需要独特并与您的应用程序一起使用的东西时,请考虑单例。

【讨论】:

以上是关于为整个应用程序引用一个类的单个实例(Firebase)的主要内容,如果未能解决你的问题,请参考以下文章

gRPC:我应该为整个应用程序使用单个客户端吗?

php单例模式之“三私一公”

混合单个实例,而不是类

c++ 创建类的实例作为引用类型

如何跨多个视图控制器引用同一个类的实例?

设计模式之单例模式