Start a new topic

Relational Data - Invalid type in JSON write (KCSKinveyRef)

I am new to Kinvey but I am experiencing difficulties using Relational Data


- I am using KinveyKit-1.40.4

- I am following the steps outlined in http://devcenter.kinvey.com/ios/guides/datastore

- I am using KCSLinkedAppdataStore

- I have confirmed that both entities are configured correctly and save individually but when I attempt to update them with a relationship (single or multiple) I get an exception.


'NSInvalidArgumentException', reason: 'Invalid type in JSON write (KCSKinveyRef)'


Can anyone suggest a possible solution? I am missing an important step?


2 people have this question

All:


Please see this example whipped up by our iOS developer Victor.  This shows how to map a relation in Kinvey:


https://github.com/KinveyApps/iOS-Sample-Relational-Data


Please let me know if you have any other questions.

All:  


We also updated our StatusShare sample application so it should be a better example of how to use references in a "real" application:  https://github.com/KinveyApps/StatusShare-iOS


Thanks,

https://github.com/KinveyApps/iOS-Sample-Relational-Data demonstrates a one-to-one relationship e.g. player.team = Team() but not the inverse as a one-to-many e.g. team.players = [Player]() which is what is where I am getting stuck

It would be nice if Kinvey support can also include "to-many"example by using array or set.


Thanks,

Damien: Thanks for those examples. It's nice to see the principle demonstrated in an extremely simple app.


However, neither of those seem to address the problem of "to-many" relationships. My last two posts were rather long, so in case you didn't read them, I'll summarize what I've found:


1. I can successfully save simple "to-one" relationships (the kind demonstrated in the sample apps you just linked to).


2. However, if the referenced entity has any properties that are relationships, the app crashes with "NSInvalidArgumentException, reason: Invalid type in JSON (KCSKinveyRef)".


3. All "to-many" relationships (modeled on the Event-Invitations example in the guide) fail with "NSInvalidArgumentException, reason: Invalid type in JSON (KCSKinveyRef)".


I created a sample app demonstrating this: https://github.com/elopinto/KinveyRelationships. So I suppose the real questions are: Are "to-many" relationships actually possible? Can you map a relationship to an entity that has its own relationships? Or is there a problem with the code in my example?

Adding to Edward's comment of not being able to save "to-many" relationship, using the latest iOS SDF lets you fetch the related items correctly. However, while saving "to-many" related data (referenced object is of type Swift Array), it will save in the backend as [null, null]. So, looks likes it knows the number of items to save, however, it does not save it correctly. 


Having said that, if the referenced objects are just being updated (that is, not new) and it has "entityId" set to a non-null value, then the "to-many" works like a charm!!!!


May be this will help the iOS SDK team to isolate the issue.


Thanks,

D. Chaudhari:


Just so I can make sure that I understand -- when you are saving this relational data, how are you going about saving it?  You would need to specify all the relevant information for it (collection, id, etc) like you would any normal object.   Also:  If you are pulling references that have "null" data that could present issues as well, as that's not an intended usage of the library.   Either you have associated data, or you don't.


Can you help me understand the use case of mapping null data to an object relation?


Also, we give an example of a 1:many relationship in our dev center.  In the last example before our Limitations on Relational data:  http://devcenter.kinvey.com/ios/guides/datastore#limitations


Thanks,

The problem is during the save, when I save an Event with a one-to-one relationship Invitation (var invitation: Invitation?) every works but when I try to save the same invitation inside to-many relationship using either an array with the data type declared (var invitations: [Invitation]?) or a mutable set (var invitationsSet: NSMutableSet?) it fails. As if the SDK does not know how to parse an array of Entities.


I have upload a sample to https://github.com/rtrevivian/KinveyRelationalData

OK. Let me try explaining:


Lets assume we have Object A and Object B. Object A contains array of Object B. Hence, 1-many relationship.


 ObjectA class: 

class ObjectA: NSObject {
    
    var entityId: String?               // Kinvey entity _id
    var title: String?                   
    var metadata: KCSMetadata?          // Create, Updated and Creator
    var items: [ObjectB]         // Referenced of type ObjectB

    override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId,
            "title" : "title",
            "metadata" : KCSEntityKeyMetadata,
            "items" : "items"
        ]
    }
    
    class override func kinveyPropertyToCollectionMapping() -> [NSObject : AnyObject]! {
        return [
            // backend to collection name
            "items" : "ItemsCollection"
        ]
    }
    
    class override func kinveyObjectBuilderOptions() -> [NSObject : AnyObject]! {
        return [
            KCS_REFERENCE_MAP_KEY : [
                // property name to object
                "items" : ObjectB.self
            ]
        ]
    }
}

  

Object B class:


 

class ObjectB: NSObject {
    
    var entityId: String?               // Kinvey entity _id
    var subTitle: String?                   
    var metadata: KCSMetadata?          // Create, Updated and Creator

    override func hostToKinveyPropertyMapping() -> [NSObject : AnyObject]! {
        return [
            "entityId" : KCSEntityKeyId,
            "subtitle" : "subtitle",
            "metadata" : KCSEntityKeyMetadata
        ]
    }
 
    }

 

Now, lets say I create an ObjectA and try to save it, it will run into the issue or get [null, null] as reference entries in my collection:

 

"NSInvalidArgumentException, reason: Invalid type in JSON (KCSKinveyRef)

 Why? Because ObjectA contains array of ObjectB in the ObjectA.items property. And Since I haven't yet created ObjectB in the Kinvey database, ObjectB.entityId is "null". What I am trying to do/assume is that IF I save ObjectA and ObjectA contains references to ObjectB, it will also create ObjectB items in the ObjectB collection.

What I am assuming (and expecting) here is that saving ObjectA via KCSLinkedAppdataStore will also create ObjectB entries mentioned in ObjectA.items. But this is not the case -- instead it inserts [null, null, null] in ObjectA's collection.


But, if I create all the ObjectB items in the Kinvey database (collection), and get the ObjectB.entityId from the DB, and then try to save ObjectA via KCSLinkedAppdataStore, then ObjectA collection will save ObjectB references in "items" field.


Looking at the example here: http://devcenter.kinvey.com/ios/guides/datastore#limitations, may be what I am expecting is incorrect. And that what I am observing is the correct behaviour. 


At this point, I just want to verify that the actual behaviour is the expected one.


Actual behaviour:

For saving 1-many relationship references, you need to create child references first before saving the parent object.

If this is the case, you may want to highlight this in your datastore documentation in a yellow box.


Thanks,


Damien:


I realize you're responding to D Chaudhari's message and the world doesn't revolve around me, but I find it rather frustrating that my questions and code examples are being ignored. You have mentioned the example in the dev center and the dev center's explanation of limitations, but as I've posted several times, I have copied that example and run it in a sample app, and it does not work.


Here is the Event class, copied directly from the example: https://git.io/v2j2b

Here is the Invitation class, copied directly from the example: https://git.io/v2jas

And here is my attempt to save them in a one-many relationship: https://git.io/v2jai


I realize that my attempt to save might be flawed, but I can't figure out why, and it would be wonderful if someone could explain it. It would help me and, I think, the other developers following this thread.


It would also be nice if someone could explain why my saves fail when the referenced objects have properties that are KinveyRefs. I include well-commented examples of that in that GitHub repo.


Thanks


1 person likes this

All,


We are currently reviewing multiple code submissions by your guys and we are working to see if there are issues with our implementation of how relational objects are implemented.  If it turns out there is a bug, it will be addressed in a future version of the SDK.  In the event that it is poorly documented, we will follow up with making the documentation more robust.   It is worth noting that Kinvey development teams observe 2 week sprints and the current sprint ends today (with the next one beginning tomorrow), so there is a bit of a time crunch for our team to finish other things before addressing this.  I have asked one of our developers to take a look at this and I will update this post with his findings.  


Thank you all for your reports, code samples, and help in addressing this issue.



All,


Using code provided from a few people here (Edward / D Chaudhari, Richard) we have been able to recreate the issue that you guys described above and have filed this as a ticket to be addressed moving forward.   I believe our current development sprint begins today.  I am uncertain of other items that would be of competing priority, but I would expect a patch to our SDK in no longer than 2 weeks time (the end of the sprint) and very likely before then.


Thanks again for your help.


1 person likes this

Damien:


Thank you very much for looking into this for us, and I really appreciate the responsiveness of the dev team over there.

Edward,


I'm just glad that I'm able to help a group of developers out with something, normally it's me writing to Jetbrains about how something in their IDE doesn't work exactly how I want it to, and then it turns out to be my fault.  It's wonderful to have developers finding and reporting bugs in our libraries because it makes the platform better for everyone.


Thanks again :)

Ditto to Edward LoPinto's last comment. Great work guys.
Login or Signup to post a comment