简体   繁体   English

两个重叠的 Firestore 侦听器是否会为同一文档更新账单?

[英]Do two Firestore listeners that overlap bill for the same document update?

I have two listeners both observing the same collection 'Tasks'.我有两个听众都在观察同一个集合“任务”。

  • One query retrieves tasks that are incomplete (completed == false)一个查询检索未完成的任务(已完成 == false)
  • The other query retrieves complete tasks within the last 24 hours (completed == true && completionDate > (Date - 24 hours))另一个查询检索过去 24 小时内完成的任务(完成 == true && completionDate > (Date - 24 hours))

Due to this logic the two listeners happen to overlap each other.由于这种逻辑,两个听众碰巧彼此重叠。 If I update a task to complete.如果我更新一个任务来完成。 Both snapshot listeners will run.两个快照侦听器都将运行。 This is the same document however.然而,这是同一份文件。

Q: Would I get charged TWICE for just updating one document?问:我是否会因为仅更新一个文档而被收取两次费用? or will the listeners know that the same document has been updated once and will only be billed once?或者听众会知道同一个文档已经更新了一次并且只会被计费一次?

class TaskData: ObservableObject {
    @Published var tasks: [Task] = []
    @Published var incompleteTasks: [Task] = []
    @Published var completedTasks: [Task] = []
    
    private var db = Firestore.firestore()
    private var incompleteTaskslistenerRegistration: ListenerRegistration?
    private var completedTasksListenerRegistration: ListenerRegistration?
    
    init() {
        subscribe()
        
        Publishers
            .CombineLatest($completedTasks, $incompleteTasks)
            .dropFirst()
            .map { $0 + $1 }
            .assign(to: &$tasks)
    }
    
    deinit {
        unsubscribe()
    }
    
    func subscribe() {
        guard let userId = Auth.auth().currentUser?.uid else { return }
                
        if incompleteTaskslistenerRegistration != nil || completedTasksListenerRegistration != nil {
            unsubscribe()
        }
        
        let completedTasksQuery = db.collection("tasks")
            .whereField("userId", isEqualTo: userId)
            .whereField("completed", isEqualTo: true)
            .whereField("completedDate", isGreaterThan: Date().advanced(by: -86400))
        
        completedTasksListenerRegistration = completedTasksQuery.addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("No documents in 'tasks' collection")
                return
            }
            self.completedTasks = documents.compactMap { queryDocumentSnapshot in
                try? queryDocumentSnapshot.data(as: Task.self)
            }
        }
        
        let incompleteTasksQuery = db.collection("tasks")
            .whereField("userId", isEqualTo: userId)
            .whereField("completed", isEqualTo: false)
        
        incompleteTaskslistenerRegistration = incompleteTasksQuery.addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("No documents in 'tasks' collection")
                return
            }
            self.incompleteTasks = documents.compactMap { queryDocumentSnapshot in
                try? queryDocumentSnapshot.data(as: Task.self)
            }
        }
    }
    
    func unsubscribe() {
        if incompleteTaskslistenerRegistration != nil {
            incompleteTaskslistenerRegistration?.remove()
            incompleteTaskslistenerRegistration = nil
        }
        if completedTasksListenerRegistration != nil {
            completedTasksListenerRegistration?.remove()
            completedTasksListenerRegistration = nil
        }
    }
}

Edit 1编辑 1

I just want to clarify that the reason I have the query for retrieving completed tasks for the past 24 hours is so that users are able to uncheck or make changes in that period.我只是想澄清一下,我查询过去 24 小时内已完成任务的原因是为了让用户能够在该期间取消选中或进行更改。 It will then be no longer fetched.然后它将不再被提取。 I don't want add a listener that fetches all the tasks ever made as that would start costing a lot and I don't want to implement pagination as I lose that real-time updating and pagination for listeners is rather strenuous.我不想添加一个监听器来获取所有曾经做过的任务,因为这会开始花费很多,我不想实现分页,因为我失去了实时更新和监听器的分页是相当费力的。

Cloud Firestore charges you for the number of documents you read, write and delete , so you are charged for a read each time a document in the result is updated. Cloud Firestore 会根据您读取、写入和删除的文档数量向您收费,因此每次更新结果中的文档时都会向您收取读取费用。

Since you have two active listeners that run the same document, the first listener will need to get or check the data from the server (document) while the second listener can read it from cache.由于您有两个运行同一文档的活动侦听器,因此第一个侦听器需要从服务器(文档)获取或检查数据,而第二个侦听器可以从缓存中读取它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 每次应用程序重新启动时,Firestore snapshost() 侦听器是否会读取每个数据的初始文档? - Does Firestore snapshost() listeners do an initial document read every data every time the app restarts? 在 Google Cloud Firestore 的批量更新中删除并重新创建相同的文档 - Deleting and recreating the same document in a batch update in Google Cloud Firestore Firestore 在查询后更新文档 - Firestore Update a document after a query 带有变音符号的 Firestore 文档,两个不同的“ö” - Firestore document with umlaut, two different "ö" 在返回所有异步函数以更新 firestore 文档之前,如何等待 NodeJS 中的多个异步函数? - How do I wait for multiple async functions in NodeJS before returning them all to update a firestore document? 同一文档中各个字段的多个并发更新是否需要事务? - Do multiple, concurrent update of individual fields in the same document require a transaction? 使用 REST api 更新 Firestore 文档 - Firestore document update using REST api flutter firestore 中同一文档的多个事务失败 - Multiple transactions to same document failure in flutter firestore firestore set operator 不添加任何文件 - firestore set operator do not add any document 没有 id 的 firestore 文档更新数据 - firestore document update data without id
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM