Skip to content

fetchIfNeededInBackgroundWithBlock : [Error]: Object not found. (Code: 101, Version: 1.14.1) #987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
burf2000 opened this issue Jul 21, 2016 · 15 comments

Comments

@burf2000
Copy link

burf2000 commented Jul 21, 2016

So I have spent the day trying to track this down.
History, moving from Parse to Parse Server (latest version of all)
I have a website that creates a record (Search) and attaches a couple of images to it (SearchPicture) for which it creates a relationship (Parse.Object.extend("SearchPicture")).

This works perfect in Parse.
On the iOS end, we load up the Search, and loop through its relationships to SearchPictures and use fetchIfNeededInBackgroundWithBlock.

Moving it to Parse Server, I get [Error]: Object not found. (Code: 101, Version: 1.14.1), I can see the ID of the record it is trying to find (gq5h0xddGA) and I can see the record in Mongo :

_{ "_id" : "gq5h0xddGA", "searchPictureImage" : "4992d20cad4f3d8c90804efa42f6475a_Screen Shot 2016-07-15 at 13.41.23.png", "_created_at" : ISODate("2016-07-21T13:31:18.592Z"), "updated_at" : ISODate("2016-07-21T13:31:18.592Z") }

If I just query the table normally (SearchPicture) in iOS it works fine and fetchIfNeededInBackgroundWithBlock is successful.

So it seems to be the link between Search and SearchPicture that causes fetchIfNeededInBackgroundWithBlock to fail

@burf2000
Copy link
Author

I would say this is related to ##986

@acegreen
Copy link

acegreen commented Jul 21, 2016

"If I just query the table normally (SearchPicture) in iOS it works fine and fetchIfNeededInBackgroundWithBlock is successful."

If you query SearchPicture directly, why would you need to do fetchIfNeeded? Isn't it already the object you wanted from Search (ie the relationship you were looking to watch). I understand that quering SearchPicture directly is a workaround to check if it works but at that point you don't need fetchIfNeeded...

Also regarding the issue, can you try to put your fetch code in a way that it loads twice. As mentioned in my issue, the first time around the error appears, when I open that view again and cause another call to be made, the data is returned. So basically put your code in viewDidAppear() and see if coming to that view twice makes it appear the second time around.

@burf2000
Copy link
Author

Good points well made Acegreen, of course fetchIfNeededInBackgroundWithBlock works normally, sorry I have not used parse for sometime, picking up a old project. I will see if call it twice fixes the issue

@burf2000
Copy link
Author

Calling it multiply times does not help. I am using local storage and I did try fetchInBackgroundWithBlock

@acegreen
Copy link

acegreen commented Jul 21, 2016

fetchIfNeededInBackgroundWithBlock in that case is not needed at all. If you use that work around, you are going to find them in your query and you have them. fetchIfNeededInBackgroundWithBlock is necessary in the original issue because you are querying the Search objects and they have relationships that might not have been included in your query (includeKey..) and thats why you need to fetch them on a per need basis.

Another point just for FYI, if you know you will always need SearchPicture when you query Search objects then include it in your query and you will not need to fetch or you won't need to do your workaround.

searchQuery.includeKey("SearchPictures")

@burf2000
Copy link
Author

Now searchQuery.includeKey("SearchPictures") is a good idea, thank you mate, that could fix my issue

@acegreen
Copy link

Yea it will not really fix the fundamental problem in fetchIfNeededInBackgroundWithBlock but it might be an option in your case if you know you will always want it in your query.

@burf2000
Copy link
Author

Hmm maybe query.includeKey("searchPictures") is broken to, so my object comes back like

<Search: 0x7a5550c0, objectId: WezgvgpQFI, localId: (null)> {
searchDetails = "Age:sdfsdf\nHeight:sdfsdf\nCurrent Clothing:sdfsdf\nLast know Location:sdfsdf\nRadio Channel: sdfdsf";
searchId = "Search 1";
searchInitialSearch = "<PFGeoPoint: 0x7ce5b6a0, latitude: 51.518678, longitude: -0.631800>";
searchPictures = (
);
searchTitle = dfdsfds;
}])

However mongo says

{ "_id" : "WezgvgpQFI", "searchPictures" : [ { "__type" : "Pointer", "className" : "searchPictures", "objectId" : "gq5h0xddGA" } ], "searchInitialSearch" : [ -0.6317996978759766, 51.51867760878029 ], "searchTitle" : "dfdsfds", "searchDetails" : "Age:sdfsdf\nHeight:sdfsdf\nCurrent Clothing:sdfsdf\nLast know Location:sdfsdf\nRadio Channel: sdfdsf", "searchId" : "Search 1", "_created_at" : ISODate("2016-07-21T13:31:26.821Z"), "_updated_at" : ISODate("2016-07-21T13:31:26.821Z") }

@acegreen
Copy link

acegreen commented Jul 21, 2016

its not broken, just not showing fields which is expected when you spit it out. try just using it as you normally would.

@burf2000
Copy link
Author

I do try using it and its empty, which I know it is not

@burf2000
Copy link
Author

Appears to not work in Android either... I feel this seems very odd

@burf2000
Copy link
Author

burf2000 commented Jul 22, 2016

So trying to debug this using curl
curl -X GET
-H "X-Parse-Application-Id: lowlands"
-H "X-Parse-REST-API-Key: ABCDEFG123456"
http://localhost:1337/parse/classes/Search/WezgvgpQFI

_{"objectId":"WezgvgpQFI","searchPictures":[{"__type":"Pointer","className":"searchPictures","objectId":"gq5h0xddGA"}],"searchInitialSearch":{"_type":"GeoPoint","latitude":51.51867760878029,"longitude":-0.6317996978759766},"searchTitle":"dfdsfds","searchDetails":"Age:sdfsdf\nHeight:sdfsdf\nCurrent Clothing:sdfsdf\nLast know Location:sdfsdf\nRadio Channel: sdfdsf","searchId":"Search 1","createdAt":"2016-07-21T13:31:26.821Z","updatedAt":"2016-07-21T13:31:26.821Z"}burfies1-MacBook:LowlandRescueWeb burfies1$

But if I do
curl -X GET
-H "X-Parse-Application-Id: lowlands"
-H "X-Parse-REST-API-Key: ABCDEFG123456"
--data-urlencode 'include=searchPictures'
http://localhost:1337/parse/classes/Search/WezgvgpQFI

{"objectId":"WezgvgpQFI","searchPictures":[],"searchInitialSearch":{"__type":"GeoPoint","latitude":51.51867760878029,"longitude":-0.6317996978759766},"searchTitle":"dfdsfds","searchDetails":"Age:sdfsdf\nHeight:sdfsdf\nCurrent Clothing:sdfsdf\nLast know Location:sdfsdf\nRadio Channel: sdfdsf","searchId":"Search 1","createdAt":"2016-07-21T13:31:26.821Z","updatedAt":"2016-07-21T13:31:26.821Z"}burfies1-MacBook:LowlandRescueWeb burfies1$

@burf2000
Copy link
Author

So more than ever I am convinced this is a bug. I have re-written the code to actually just get the objectID from the relationship then manually retrieve the record and it works fine.

New code
let searchPictures : [PFObject] = Search.sharedInstance.selectedPerson["searchPictures"] as! [PFObject]

        for searchPicture : PFObject in searchPictures {

            var query = PFQuery(className:"SearchPicture")
            query.getObjectInBackgroundWithId(searchPicture.objectId!) {
                (searchPicture: PFObject?, error: NSError?) -> Void in
                if error == nil && searchPicture != nil {

                        let file : PFFile = searchPicture!["searchPictureImage"] as! PFFile

                        file.getDataInBackgroundWithBlock({ (data, error) -> Void in

                            if error == nil {
                                if let image = UIImage(data: data!) {
                                    Search.sharedInstance.missingPersonPhotosArray.append(image)

                                    if Search.sharedInstance.missingPersonPhotosArray.count > 0 {
                                        // Add 1st image to missing person page
                                        dispatch_async(dispatch_get_main_queue()) {
                                            self.missingPersonMainImage.image = Search.sharedInstance.missingPersonPhotosArray.first
                                            self.spinner.stopAnimating()
                                            self.spinner.hidden = true
                                        }
                                    }
                                } else {
                                    self.spinner.stopAnimating()
                                    self.spinner.hidden = true
                                }
                            } else {
                                self.spinner.stopAnimating()
                                self.spinner.hidden = true
                            }

                        })

                } else {
                    self.spinner.stopAnimating()
                    print(error)
                }
            }

Old code
let searchPictures : [PFObject] = Search.sharedInstance.selectedPerson["searchPictures"] as! [PFObject]

        for searchPicture : PFObject in searchPictures {

            searchPicture.fetchIfNeededInBackgroundWithBlock({ (Object, error) -> Void in
                print (error)
            if error == nil {
                let file : PFFile = searchPicture["searchPictureImage"] as! PFFile

                file.getDataInBackgroundWithBlock({ (data, error) -> Void in

                    if error == nil {
                        if let image = UIImage(data: data!) {
                            Search.sharedInstance.missingPersonPhotosArray.append(image)

                            if Search.sharedInstance.missingPersonPhotosArray.count > 0 {
                                // Add 1st image to missing person page
                                dispatch_async(dispatch_get_main_queue()) {
                                    self.missingPersonMainImage.image = Search.sharedInstance.missingPersonPhotosArray.first
                                    self.spinner.stopAnimating()
                                    self.spinner.hidden = true
                                }
                            }
                        } else {
                            self.spinner.stopAnimating()
                            self.spinner.hidden = true
                        }
                    } else {
                        self.spinner.stopAnimating()
                        self.spinner.hidden = true
                    }

                })

            } else {
                self.spinner.stopAnimating()
            }

            })

@acegreen
Copy link

running a query for every object is super inefficient. if you are going to manually grab them, then at least do one query and whereKey:ContainedIn and give it an array of searchPictures

@stale
Copy link

stale bot commented Sep 19, 2018

This issue has been automatically marked as stale because it has not had recent activity. If you believe it should stay open, please let us know! As always, we encourage contributions, check out the Contributing Guide

@stale stale bot added the wontfix label Sep 19, 2018
@stale stale bot closed this as completed Sep 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants