首页 > 解决方案 > 为什么以前从堆栈中弹出的视图仍然处于活动状态

问题描述

我在 swiftUI 中有这个卡车驾驶应用程序,我使用火力基地来登录和注销用户。问题是,当我使用一个用户登录时,它的所有基本功能都会被触发,在我从当前用户注销并进入新用户后,旧用户的功能仍在发挥作用。我认为这可能与 onAppear 方法中的 firebase 函数有关。不过我不确定。

这是firebase代码。我不认为我查询的内容与解决方案有任何关系,所以我不会解释它,但如果你认为它比请告诉我。

        .onAppear(perform: {

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge]) { (_,_) in
            
        }
   
            myDrivers = []
              getEmails()
        
        db.collectionGroup("resources").whereField("control", isEqualTo: true).addSnapshotListener { (snapshot, err) in
            
            if myDrivers.count == 0{}
            
            else{
            
            if err != nil{print("Error fetching motion status: \(err)")}
            
            if ((snapshot?.documents.isEmpty) != nil){}
            

// 获取所有的 driverLocation 文档

            for doc in snapshot!.documents{
                
                if myDrivers.contains(doc.reference.parent.parent!.documentID){
              
                let isDriving = doc.get("isDriving") as! Bool
                let isStopped = doc.get("isStopped") as! Bool
                let notified = doc.get("notified") as! Bool
                
                if (isDriving == false && isStopped == false) || notified{}
                
                else{
                    

// 获取驱动程序的名称

                    doc.reference.parent.parent?.getDocument(completion: { (snapshot, err) in
                        
                        if err != nil{print("Error parsing driver name: \(err)")}
                        
                        let firstName = snapshot?.get("firstName") as! String
                        let lastName = snapshot?.get("lastName") as! String
                        
                        self.notifiedDriver = "\(firstName) \(lastName)"
            
                    })
                
                    

// 逻辑

                    if isDriving{
                        
                        send(notiTitle: "MyFleet", notiBody: "\(notifiedDriver) is back on the road.")
                        showDrivingToast.toggle()
                        doc.reference.updateData(["notified" : true])
                        
                    }else if isStopped{

                       send(notiTitle: "MyFleet", notiBody: "\(notifiedDriver) has stopped driving.")
                        showStoppedToast.toggle()
                        doc.reference.updateData(["notified" : true])
                        
                    }
                }
            }
                else{}    
            }

        }
    }
})

标签: iosswiftfirebasegoogle-cloud-firestoreswiftui

解决方案


当视图控制器离开时,侦听器不会死。他们保持活跃。

当视图关闭或用户导航离开时,通过特定侦听器的处理程序管理它们很重要。这是删除特定侦听器的方法

let listener = db.collection("cities").addSnapshotListener { querySnapshot, error in
    // ...
}

然后稍后

// Stop listening to changes
listener.remove()

或者,如果您的用户正在注销,您可以使用removeAllObservers(用于 RealtimeDatabase)一次将它们全部删除,注意

必须为每个建立了侦听器的子引用再次调用 removeAllObservers

对于 Firestore,将侦听器存储在侦听器数组类 var 中,当您想要全部删除它们时,只需遍历数组元素调用 .remove() 即可。

Firebase 入门指南中的其他信息分离侦听器


推荐阅读