Skip to content

Pinning PFObject with pointer corrupts local datastore #535

Open
@mtsanford

Description

@mtsanford

Tested on version 1.9.1. If an object C1 pointing to P1 is pinned (and not saved), then an object C2 pointing to P2 is pinned, P1 is corrupted in the datastore. This seems to be the minimum condition to reproduce:

func letsCorruptTheDatastore(sender: AnyObject) {

        // create a post with a comment and pin it
        let post1 = PFObject(className:"Post")
        post1["text"] = "I am post #1"
        let comment1 = PFObject(className:"Comment")
        comment1["post"] = post1

        comment1.pinInBackground().continueWithSuccessBlock {
            (task: BFTask!) -> AnyObject! in

            // Make another post with comment and pin it
            let post2 = PFObject(className:"Post")
            post2["text"] = "I am post #2"
            let comment2 = PFObject(className:"Comment")
            comment2["post"] = post2
            return comment2.pinInBackground()
        }.continueWithSuccessBlock {
            (task: BFTask!) -> AnyObject! in

            // Now try to query local Post objects
            let query = PFQuery(className:"Post")
            query.fromLocalDatastore()
            return query.findObjectsInBackground()
        }.continueWithBlock {
            (task: BFTask!) -> AnyObject! in
            if (task.error != nil) { print(task.error) }
            else if (task.result != nil) { print(task.result) }
            return nil 
        } 
    }

The query fails with this error:

Error Domain=Parse Code=120 "Attempted to fetch and object offline which was never saved to the offline cache" UserInfo={error=Attempted to fetch and object offline which was never saved to the offline cache, code=120, NSLocalizedDescription=Attempted to fetch and object offline which was never saved to the offline cache}

Looking at the sqlite database, it is apparent that the data has been corrupted (nulled out), which results in queries on the corrupted data always failing.

sqlite> 
sqlite> select * from ParseObjects where className = "Post";
41067A2D-5BE8-4BD8-8902-C453E790C69B|Post||{"className":"Post","__complete":true,"__operations":[{"__updatedAt":{"iso":"2015-11-10T16:58:07.687Z","__type":"Date"},"__uuid":"FD2A80A9-7E9F-469E-95DC-2DF4A0014361","text":"I am post #2"}],"isDeletingEventually":0}|0
616B0182-1A5B-4F44-BE05-204A80AAE557|Post|||0
sqlite> select * from ParseObjects where className = "Comment";
B847E0D4-725A-464D-AEA9-51D4CADCD66A|Comment||{"className":"Comment","__complete":true,"__operations":[{"__updatedAt":{"iso":"2015-11-10T16:58:07.691Z","__type":"Date"},"post":{"uuid":"616B0182-1A5B-4F44-BE05-204A80AAE557","__type":"OfflineObject"},"__uuid":"546E9AEF-63B7-460A-A130-BD547D11DB45"}],"isDeletingEventually":0}|0
AB5FAF2A-C698-4A4F-8011-1FC3602247D3|Comment||{"className":"Comment","__complete":true,"__operations":[{"__updatedAt":{"iso":"2015-11-10T16:58:07.688Z","__type":"Date"},"post":{"uuid":"41067A2D-5BE8-4BD8-8902-C453E790C69B","__type":"OfflineObject"},"__uuid":"D58AAEEE-093F-4C71-B002-F6F10B3E05D5"}],"isDeletingEventually":0}|0
sqlite> 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions