如何根据不断更新的状态触发一次通知

Posted

技术标签:

【中文标题】如何根据不断更新的状态触发一次通知【英文标题】:How to trigger notifications once depending on a constantly updated state 【发布时间】:2021-03-03 03:18:00 【问题描述】:

我正在使用 SwiftUI 为货运公司制作车队管理应用程序,现在我无法在每次司机开始或停止驾驶时通知雇主。我使用 CMMotionActityManager 将驱动程序动作更新到我的 Firestore 数据库。在雇主端,我让他们听取司机动态的更新。

问题是我在 snapshotListener 闭包中有雇主的监听代码。这意味着,如果雇主有多个司机,则每次一名司机的运动状态发生变化时,它不会通知雇主其司机运动的最新变化,而是通知他们过去的ALL变化所有他们雇用的司机的动议。

这是将运动数据发送到数据库的函数。

    func setMotionUpdates()
    

    
    let motionDoc =  db.collection("driverData").document(email).collection("resources").document("userLocation")

    if CMMotionActivityManager.isActivityAvailable() 
        
        
        motionManager.startActivityUpdates(to: OperationQueue.main)  (motion) in
          
            
            
            
            if motion!.automotive
            
                motionDoc.updateData(["isDriving": true, "isStopped" : false])
                
                
            
            else if motion!.stationary
                
                motionDoc.updateData(["isStopped": true, "isDriving" : false])

               
            
            
           
            
    
        

    

这是读取该数据并通知雇主的代码

            db.collectionGroup("resources").whereField("control", isEqualTo: true).addSnapshotListener  (snapshot, err) in
            
           
            
            if err != nilprint("Error fetching motion status: \(err)")
            
            if ((snapshot?.documents.isEmpty) != nil)print("4")
            

//获取所有driverLocation文件

            for doc in snapshot!.documents
              
                let isDriving = doc.get("isDriving") as! Bool
                let isStopped = doc.get("isStopped") as! Bool
                
                if isDriving == false && isStopped == false
     
                    
                
                
                else

// 获取驱动的名字

                    doc.reference.parent.parent?.getDocument(completion:  (snapshot, err) in
                        
                        if err != nilprint("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()
                        
                    else if isStopped

                       send(notiTitle: "MyFleet", notiBody: "\(notifiedDriver) has stopped driving.")
                        
                        showStoppedToast.toggle()
                  
                        
                    
                
            
            
        

【问题讨论】:

【参考方案1】:

是的,看来我明白了

我所做的是在我的数据库中创建了一个“通知”布尔字段,该字段将通过运动活动更新到数据库中。每当 CMMotionActivityManager 更新运动状态时,它都会将 notify 设置为 false 以及我需要进行的所有其他更新。

            motionManager.startActivityUpdates(to: OperationQueue.main)  (motion) in
          
            
            
            
            if motion!.automotive
            
                motionDoc.updateData(["isDriving": true, "isStopped" : false, "notified": false])
                
                
            
            else if motion!.stationary
                
                motionDoc.updateData(["isStopped": true, "isDriving" : false, "notified": false])

               
            
            
           
            
    

由于我正在监听雇主端的更新,snapshotListener 代码将重新运行并检查他们是否已经收到关于动作更新的通知。

                    if (isDriving == false && isStopped == false) || notified == true
     
                    
                

我添加了“|| notify == true”来检查我从驱动程序数据库收到的通知字段是否 == true。如果这是真的,我不会运行通知我的驱动程序的代码。如果为假,我将运行该代码。

【讨论】:

【参考方案2】:

您需要在客户端监听驱动程序更改吗?如果没有,您可以使用带有firestore trigger 的云功能。当文档更新时,您可以设置向雇主发送推送通知的功能。

【讨论】:

是的,我需要倾听变化。我想我已经解决了这个问题,但是,验证雇主是否已经通知的逻辑令人困惑。目前,如果我的司机正在开车,每次我打开应用程序时,我都会收到几天前可能设置的司机的运动状态的通知。我想要它,以便在第一次更新运动状态时,我会在当前时间收到通知,并且不会再收到通知。

以上是关于如何根据不断更新的状态触发一次通知的主要内容,如果未能解决你的问题,请参考以下文章

检测应用程序处于后台/非活动状态时是不是触发了本地通知

本地通知 UNTimeIntervalNotificationTrigger triggerWithTimeInterval 每 1 分钟触发一次 如何停止

如何将 ID 分配给 toastr.js 通知并根据需要进行更新

如何根据contentHeight不断更新图像?

如何以编程方式确定推送通知状态?

以不同的时间重复通知