微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift中的Firestore-侦听器产生不必要的读取

如何解决Swift中的Firestore-侦听器产生不必要的读取

我有一个使用快照侦听器来侦听特定文档中数据的应用程序。但是,当文档中的字段被更新时,数据将被读取7-10倍。永远不要读一次,也永远不要读文档中的字段数,它似乎总是一个任意数。另外,当打印出读取的数据时,似乎每个打印输出都是相同的,除了我没有设置的几个字段(例如数组打印出“ <__ nsarraym>”,但是每次打印的数量都会改变)。结果,我的应用程序的最低使用量导致5-10k次读取。我正在尝试减少读取次数,但我不知道该怎么做,但是该应用程序必须在数据更新时进行读取,但是我的两个问题是:

  1. 当我从侦听器中打印数据时,打印出的每个数据是否表示单独的读取操作?和

  2. 是否可以通过某种方式使更新收到警报,但要等到实际执行读取操作,直到数据更新,然后在每次更新任何字段时执行一次读取而不是多次读取?还是在发生多次写入时减少读取的另一种策略?

不确定这是否有帮助,但这是我用来执行读取的代码...它几乎是firestored sdk中的标准代码

 env.db.collection(env.currentSessionCode!).document(K.FStore.docName).addSnapshotListener { [self] documentSnapshot,error in
            guard let document = documentSnapshot else {
                print("Error fetching snapshot: \(error!)")
                return
            }
            guard let data = document.data() else {
                print("Document data was empty.")
                return
            }
                        

            self.env.data1 = data[K.FStore.data1] as? String ?? "????"
            self.env.data2 = data[K.FStore.data2] as? String ?? "????"
            self.env.data3 = data[K.FStore.data3] as? [String] ?? ["????"]
            self.env.data4 = data[K.FStore.data4] as? [String] ?? ["????"]
            self.env.data5 = data[K.FStore.data5] as? Double ?? 0
            self.env.data6 = data[K.FStore.data6] as? Double ?? 0
            self.env.data7 = data[K.FStore.data7] as! Bool
            self.env.data8 = data[K.FStore.data8] as! Bool
            
            print("Current data: \(data)")
            

Update-为澄清起见,我将数据更新为firebase的方式是使用环境对象,并在环境中更改/更新新数据时使用“ didSet”在firebase上进行更新...我认为这可能是问题的根源,因为didSet上调用函数每次调用时都会运行4-5次...

相关代码

@Published var data1: String {
        didSet {
            postValuesToFB(fb: K.FStore.data1,string: data1)
        }
    }

    func postValuesToFB(fb: String,string: String) {
        guard let code = currentSessionCode else {
            fatalError("Error - Connection Check - no value for current session code in Global Env")
        }
        
        let docRef = db.collection(code).document(K.FStore.docName)
        docRef.getDocument { document,_ in
            guard let document = document else {
                return
            }
            if document.exists {
                let session = self.db.collection(code).document(K.FStore.docName)

                session.updateData([
                    fb: string,K.FStore.dateLastAccessed: FieldValue.serverTimestamp(),])

                return
            }
        }
    }

解决方法

根据您的评论,听起来好像您没有添加任何代码来删除侦听器。基于此,假设您的代码会随着时间的推移添加许多侦听器,并且每个正在被要求进行每个更改是相对安全的。

您应该花点时间考虑一下应用程序的体系结构,并确定何时是不再需要侦听器的适当时间。通常,这与负责显示查询数据的任何组件的生命周期相对应。查看getting realtime updates的文档,尤其是detaching a listener的部分。由您决定删除监听器的正确时间,但是您绝对不希望像现在一样“泄漏”监听器。

,

对于Firestore初学者来说,意外读取费用的常见来源是Firebase控制台本身。当该控制台显示Firestore内容时,也会向您收费。为了确保您正确评估代码的影响,请在Firebase控制台关闭的情况下对其进行测试。

当我从侦听器打印数据时,打印出的每个数据是否表示单独的读取操作?

不是。当您在服务器上代表您阅读文档时,您需要为阅读文档支付费用。您并没有因多次打印相同的DocumentSnapshot而受到表扬。

有什么方法可以让侦听器收到有关更新的警报,但要等到实际执行读取操作之后,数据才被更新

不。要知道文档已更改,服务器需要阅读它。因此,这需要付费的读取操作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。