代码之家  ›  专栏  ›  技术社区  ›  lurning too koad

Firestore延迟补偿快照返回在批处理和事务之间不同

  •  0
  • lurning too koad  · 技术社区  · 6 年前

    let db = Firestore.firestore()
    let batch = db.batch()
    let timestamp = FieldValue.serverTimestamp()
    
    batch.updateData([
        "private.index.\(someId)": ["count": 0, "timestamp": timestamp]
    ], forDocument: db.collection("someCollection").document(uId))
    
    batch.deleteDocument(db.collection("anotherCollection").document("\(uId)-\(someId)"))
    
    batch.commit { (error) in
    
        if let error = error {
            print(error)
        }
    
    }
    

    如果快照侦听器忽略返回 hasPendingWrites ,数据很好,因为它来自服务器(这是正确的)。但是,如果快照侦听器允许延迟补偿数据,我会得到:

    ["count": 0, "t": <null>]]
    

    来自服务器(和事务)的数据如下所示:

    ["count": 0, "t": <FIRTimestamp: seconds=1586033607 nanoseconds=198000000>]]
    

    时间戳不应该为零。

    同样奇怪的是,如果我在一个事务中执行相同的任务,就不会有问题,即使有延迟补偿数据(这是正确的)。

    db.runTransaction({ (trans, errorPointer) -> Any? in
    
        trans.updateData([
            "private.index.\(someId)": ["count": 0, "timestamp": timestamp]
        ], forDocument: db.collection("someCollection").document(uId))
    
        trans.deleteDocument(db.collection("anotherCollection").document("\(uId)-\(someId)"))
    
        return nil
    
    }) { (_, error) in
    
        if let error = error {
            print(error)
        }
    
    }
    

    批处理写入有时会不会给出一致的延迟补偿结果,因为它们不像事务那样工作?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Doug Stevenson    6 年前

    我最近写了一篇关于这个的博文 behavior of server timestamps

    如果您确实需要快照中尚未同步的时间戳,则应该 getData() 没有参数获取快照中的数据。相反,你应该使用 getData(serverTimestampBehavior) . 你通过的论点:

    配置尚未设置为其最终值的服务器时间戳的行为。

    ServerTimestampBehavior 让您选择是否需要估计值、无(如您现在所见,为零)或字段的上一个值。听起来你想要一个估计。