Is the Carekit data corrupted?

124 views Asked by At

I am sending the data collected by carekit to firebase. The date in firebase(ex.updateDate) is float.

Cloud Firestore:

{"updatedAt":"2021-07-11 06:28:22.420435 UTC","revisions":[{"knowledgeVector":
{"processes":[{"clock":"34","id":"3353F0B6-8B59-4B86-B4AD-A74EE76DCD93","__key__":
{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"entities":[{"type":"task","object":
{"instructions":"Tap the button below anytime you experience nausea.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.410913,"title":"Track your
 nausea!!","uuid":"1942E91C-F0C3-410D-9D06-F5F6B3859D0E","schedule":{"elements":
[{"start":"645980400","duration":{"isAllDay":true,"__key__":
{"namespace":"","app":"","path":""}},"interval":
{"weekOfYear":"0","year":"0","second":"0","minute":"0","hour":"0","month":"0","day":"1","
__key__":{"namespace":"","app":"","path":""}},"text":"Anytime throughout the
 day","__key__":{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"createdDate":646268927.410907,"id":"nausea","impact
sAdherence":false,"effectiveDate":
{"integer":"645980400","provided":"integer"},"phoneNumbers":[],"messagingNumbers":
[],"emailAddresses":[],"values":[],"__key__":
{"namespace":"","app":"","path":""}},"__key__":{"namespace":"","app":"","path":""}},
{"type":"task","object":{"instructions":"Peform Pelvic Gymnastics 5times for 10 Seconds
 Each Time.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.42012,"title":

In the carekit data output to the log with the following code, the date is a timestamp.

Log (the contents of a variable called a revisions that is exchanged when sending and receiving patient events to and from Firebase.):

[CareKitStore.OCKRevisionRecord(entities: 
[CareKitStore.OCKEntity.task(CareKitStore.OCKTask(carePlanUUID: nil, id: "nausea", title: 
Optional("Track your incontinence!!"), instructions: Optional("Tap the button below 
anytime you experience nausea."), impactsAdherence: false, schedule: 
CareKitStore.OCKSchedule(elements: [CareKitStore.OCKScheduleElement(text: Optional("Anytime throughout the day"), duration: CareKitStore.OCKScheduleElement.Duration.allDay, start: 2021-08-12 15:00:00 +0000, end: nil, interval: year: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0 weekOfYear: 0 isLeapMonth: false , targetValues: [])]), groupIdentifier: nil, tags: nil, effectiveDate: 2021-08-12 15:00:00 +0000, deletedDate: nil, uuid: Optional(E6D112BD-0E9F-430F-BF9C-4CE5D69BAC54), nextVersionUUID: nil, previousVersionUUID: nil, createdDate: Optional(2021-08-15 23:28:52 +0000), updatedDate: Optional(2021-08-15 23:28:52 +0000), schemaVersion: Optional(2.0.4), remoteID: nil, source: nil, userInfo: nil, asset: nil, notes: Optional([]), timezone: Asia/Tokyo (current))), 

I got the contents of revisions with the following code.

extension CKCareKitRemoteSyncWithFirestore {
    fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
        do {
            let data = try JSONEncoder().encode(deviceRevision)
            let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
            
            CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
                print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
                completion(error)
            }
        } catch {
            print("[putRevisionInFirestore] " + error.localizedDescription)
            completion(error)
        }
    }
    
    fileprivate func getRevisionsFromFirestore(completion: @escaping (_ revisions: [OCKRevisionRecord]) -> Void) {
        CKSendHelper.getFromFirestore(collection: collection, identifier: identifier, onCompletion: { (document, error) in
            guard let document = document,
                  let payload = document.data()?["revisions"] else {
                completion([OCKRevisionRecord]())
                return
            }
            
            do {
                let jsonData = try JSONSerialization.data(withJSONObject: payload, options: [])
                let revisions = try JSONDecoder().decode([OCKRevisionRecord].self, from: jsonData)
                completion(revisions)
                print(revisions)
            } catch {
                print("[getRevisionsFromFirestore] ERROR " + error.localizedDescription)
                completion([OCKRevisionRecord]())
            }
        })
    }
    
    fileprivate func createPullMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
        let newEntities = revisions.filter({ $0.knowledgeVector >= knowledgeVector }).flatMap({ $0.entities })
        
        var allKnowledge = OCKRevisionRecord.KnowledgeVector()
        for rev in revisions.map({ $0.knowledgeVector }) {
            allKnowledge.merge(with: rev)
        }
        
        let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
        return newRecord
    }
    
    fileprivate func createPushMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
        let newEntities = revisions.filter({ knowledgeVector >= $0.knowledgeVector }).flatMap({ $0.entities })
        
        var allKnowledge = knowledgeVector
        for rev in revisions.map({ $0.knowledgeVector }) {
            allKnowledge.merge(with: rev)
        }
        
        let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
        return newRecord
    }
    
}

I tried to convert this float date data the timestamp with the following query(BigQuery),but it was incorrect. Is there any other good solution? Thanks in advance.

SELECT FORMAT_TIMESTAMP("%Y-%m-%d %H:%M:%S", TIMESTAMP_SECONDS(CAST(updatedDate as INT64)), "Asia/Tokyo") as formatted FROM `@@@` 

1

There are 1 answers

0
user2677680 On BEST ANSWER

Gourav B,thank you for your response. I solved it.

Following your advice, in the function "putRevisionInFirestore" of the above code,I put out the original data "deviceRevision" and "json" which converted "deviceRevision" to json in the log.

As a result,the date data of the former was correct timestamp and the latter was float.

For that reason,I guessed that there was a problem with the encoding part of json and specified the encoding strategy in putRevisionInFirestore as shown below, and the date data on the firebase has changed from float to the correct timestamp.

Thank you for your help!

fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
    do {let encoder = JSONEncoder()
        encoder.dateEncodingStrategy = .iso8601
        let data = try encoder.encode(deviceRevision)
        let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
        
        CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
            print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
            print("[putRevisionInFirestore_deviceRevision]",deviceRevision)
            print("[putRevisionInFirestore_json]",json)
            completion(error)
        }
    } catch {
        print("[putRevisionInFirestore] " + error.localizedDescription)
        completion(error)
    }
}