Parse-SDK-iOS-OSX icon indicating copy to clipboard operation
Parse-SDK-iOS-OSX copied to clipboard

Unsaved children are not able to be saved when updating parent object

Open DanielsCode opened this issue 9 years ago • 17 comments

I have a simple parse schema

Class AClass

import Parse
class AClass : PFObject, PFSubclassing {
  @NSManaged var title: String
  @NSManaged var childs: [BClass]?

  override class func initialize() {
    struct Static {
        static var onceToken : dispatch_once_t = 0;
    }
    dispatch_once(&Static.onceToken) {
        self.registerSubclass()
    }
  }

   static func parseClassName() -> String {
    return "AClass"
  }
}

Class BClass

 import Parse
 class BClass : PFObject, PFSubclassing {
  @NSManaged var message: String

   override class func initialize() {
     struct Static {
         static var onceToken : dispatch_once_t = 0;
    }
    dispatch_once(&Static.onceToken) {
        self.registerSubclass()
    }
  }
  static func parseClassName() -> String {
    return "BClass"
  }
}

AppDelegate.swift

 BClass.registerSubclass()
 AClass.registerSubclass()

ViewController.swift e.g. I tried ...

  let query = AClass.query()
    query?.includeKey("childs")
    query?.getFirstObjectInBackgroundWithBlock({ (parent, error) -> Void in
        if error == nil {
            let parentObj = parent as? AClass
            print("current Message 1: \(parentObj?.childs?.last?.message)")
            parentObj?.childs?.last?.message = "Changed"
            parentObj?.saveInBackgroundWithBlock({ (success, error) -> Void in
                if success {
                    let query = AClass.query()
                    query?.includeKey("childs")
                    query?.getFirstObjectInBackgroundWithBlock({ (parent, error) -> Void in
                         if error == nil {
                            let parentObj = parent as? AClass
                            print("current Message 2: \(parentObj!.childs?.last?.message)")
                         } else {
                            print("Error: \(error)")
                        }
                    })
                } else {
                    print("Error: \(error)")
                }
            })
        } else {
            print("Error: \(error)")
        }
    })

Console Log:

current Message 1: Optional("Start")
current Message 2: Optional("Start")

I thought that parse would save recursive. First the parent object and all changed child objects. But I can't see any changes in the parse dashboard of the message field (BClass).

It is maybe the same issue as in the JS-DSK - see https://github.com/ParsePlatform/Parse-SDK-JS/issues/89

I am using Parse (1.12.0) . Any ideas?

DanielsCode avatar Feb 16 '16 21:02 DanielsCode

Update: I found out, that it is only the case if the pointer to the child is containing in a array of the parent - like

DB example on column childs of Class A: [{"__type":"Pointer","className":"BClass","objectId":"giazyTfGft"}]

If it's just a one-to-one relation it is working as expected. DB example on column singleChild of Class A: giazyTfGft

Is this a missing feature or a bug that it won't work if the pointer to the child is in an array of the parent?

DanielsCode avatar Feb 20 '16 09:02 DanielsCode

That actually sounds like a bug to me, since we explicitly do a deep save on the object, meaning that all of it's children are going to be saved.

This sounds very very strange, as we have explicit tests around this. Also, since no exceptions are being thrown I don't think it's the same issue as was in JS SDK. Any chance you can create a small repro project for this scenario? I will gladly take a deeper look, but do need more data on the initial state of the objects.

nlutsenko avatar Feb 23 '16 09:02 nlutsenko

Thank you for your feedback. We prioritize issues that have clear and concise repro steps. Please see our Bug Reporting Guidelines about what information should be added to this issue.

Please try the latest SDK. Our release notes have details about what issues were fixed in each release.

In addition, you might find the following resources helpful:

  • Documentation: https://www.parse.com/docs
  • Google Groups: https://groups.google.com/forum/#!forum/parse-developers
  • Stack Overflow: http://stackoverflow.com/tags/parse.com

parse-github-bot avatar Feb 23 '16 09:02 parse-github-bot

@nlutsenko I created a small repro project under https://github.com/DanielsCode/parse-child-saving. I hope it's clear, it was my first time. If you need additional information please let me know.

Thanks in advance.

DanielsCode avatar Feb 25 '16 22:02 DanielsCode

Awesome, thanks for the project! It help a lot! Will take a look at it, and comment here on the results.

nlutsenko avatar Feb 25 '16 23:02 nlutsenko

great, looking forward to hear from you.

DanielsCode avatar Feb 26 '16 19:02 DanielsCode

@nlutsenko any news on this topic? I am almost three weeks behind schedule with my project :/

DanielsCode avatar Mar 08 '16 21:03 DanielsCode

@nlutsenko I am sorry to bother you again - are there any updates? Please let me know if I can support you. Thanks for helping

DanielsCode avatar Mar 24 '16 13:03 DanielsCode

No updates yet, so sorry, got tangled in other things. Will try my best to get back to you soon on this.

nlutsenko avatar Mar 24 '16 19:03 nlutsenko

@nlutsenko I am seeing this problem too and have a lot of code that saves and resaves objects because of this. Any chance you have time to look into it soon?

laptobbe avatar Apr 15 '16 12:04 laptobbe

I believe am seeing a variation of this when retrieving children via the parent. i.e. if I attempt to get A.childs?.first?.message, I get network time outs. I believe the way the Parse Swift SDK is set up here, it will do searches based on the object id's stored in the parent array and then pull down the B object and retrieve the message. I will investigate some more to see if the query is sent and result are coming back, to try to isolate it as an SDK issue or a server issue.

tylerarnold avatar May 19 '16 23:05 tylerarnold

Any news on that topic? I tried Bolts (1.8.4) and Parse (1.14.2) with Swift3 - but again same strange behavior. Would love to see a fix.

DanielsCode avatar Feb 19 '17 11:02 DanielsCode

@lacker can you help?

DanielsCode avatar Apr 16 '17 13:04 DanielsCode

No updates?

DanielsCode avatar Dec 25 '17 12:12 DanielsCode

One year with no feedback? Is parse-iOS dead?

DanielsCode avatar Jan 21 '19 22:01 DanielsCode

FWIW I updated your example project to current Swift and xCode and played around with it a bit. The behaviour you described still exists which based on the discussion above is a bug. The interesting thing was that replacing

parentObj.saveInBackground { (success, error) -> Void in

with

PFObject.saveAll([parentObj!])

produced the expected behaviour e.g. the child is updated. Same with

PFObject.saveAll(inBackground:

Don't know if this is a viable work around but as I said FWIW

brianyyz avatar Jan 22 '19 19:01 brianyyz

Is this still an issue with the latest version?

noobs2ninjas avatar Mar 10 '20 16:03 noobs2ninjas