Skip to content
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

"INVALID_FIELD_FOR_INSERT_UPDATE" when using SFParentChildrenSyncUpTarget #3145

Open
Yannmm opened this issue Feb 10, 2020 · 3 comments
Open
Labels

Comments

@Yannmm
Copy link

Yannmm commented Feb 10, 2020

Please fill out the following details:

  1. Version of Mobile SDK Used: 7.3.0
  2. Issue found in Native App or Hybrid App: Native swift
  3. OS Version: 13.1
  4. Device: iPad pro
  5. Steps to reproduce:

Assume we have two classes "Parent" and "Child".

class Parent {
    let id: String
}

class Child {
    let id: String
    let parent_id: String
    let option: String
}

And my sync up configure file is like below:

{
    "syncs": [{
        "syncName": "UpSync",
        "syncType": "syncUp",
        "soupName": "soup_parent",
        "target": {
            "iOSImpl": "SFParentChildrenSyncUpTarget",
            "childrenCreateFieldlist": [
                "Id",
                "Parent_id",
                "Option"
            ],
            "parentCreateFieldlist": [
                "Id",
            ],
            "childrenUpdateFieldlist": [
                "Option"
            ],
            "parentUpdateFieldlist": [
            ],
            "parent": {
                "idFieldName": "Id",
                "sobjectType": "Parent__c",
                "modificationDateFieldName": "LastModifiedDate",
                "soupName": "soup_parent"
            },
            "relationshipType": "MASTER_DETAIL",
            "type": "rest",
            "modificationDateFieldName": "LastModifiedDate",
            "children": {
                "parentIdFieldName": "Parent_id",
                "idFieldName": "Id",
                "sobjectType": "Child__c",
                "modificationDateFieldName": "LastModifiedDate",
                "soupName": "soup_child",
                "sobjectTypePlural": "children__r"
            },
        },
        "options": {"mergeMode":"LEAVE_IF_CHANGED"}
    }]
}

Using this configuration, create and delete is working fine. But when I want to update, child record always receive 400, and the reponse is like:

{
    "body":[
        {
            "message":"Unable to create/update fields: parent_id. Please check the security settings of this field and verify that it is read/write for your profile or permission set.",
            "errorCode":"INVALID_FIELD_FOR_INSERT_UPDATE",
            "fields":[
                "parent_id"
            ]
        }
    ],
    "httpHeaders":{

    },
    "httpStatusCode":400,
    "referenceId":"a8le0000000IB31AAG"
}

Request body is like:

{
    "body":{
        "parent_id":"a0be0000009Za0qAAC",
        "option":"No"
    },
    "method":"PATCH",
    "referenceId":"a8le0000000IB31AAG",
    "url":"/services/data/v46.0/sobjects/child__c/a8le0000000IB31AAG"
}

So I guess SFDC won't allow me to update parent_id, and that's reasonable. The question is why this key-value pair is inserted into request, despite I already declare update field list contains only option.

After I looking at sdk code, I found in file SFParentChildrenSyncUpTarget.m line 417, there is code like this:

       if (parentId) {
            fields[((SFChildrenInfo *) info).parentIdFieldName] = useParentIdReference ? [NSString stringWithFormat:@"@{%@.%@}", parentId, kCreatedId] : parentId;
        }

This will insert above key-value pair into the request body. But I think this is only required when creating, not updating. So I add one more condition:

        if (parentId && isCreate) { // only insert when create
            fields[((SFChildrenInfo *) info).parentIdFieldName] = useParentIdReference ? [NSString stringWithFormat:@"@{%@.%@}", parentId, kCreatedId] : parentId;
        }

And it works like a charm.

How do you think?
please let me know. Thanks.

@wmathurin
Copy link
Contributor

wmathurin commented Feb 10, 2020

It won't complain if you select "allow reparenting" in the master-detail relationship definition.

However, I see your point. Since reparenting is disallowed by default, the code should not be adding the parent id automatically during an update (and apps that want to reparent and allow it should be responsible for adding the parent id field in their children update list).

It is a behavior change so we will evaluate whether to do it in a minor release or not.

@wmathurin wmathurin added the bug label Feb 10, 2020
@Yannmm
Copy link
Author

Yannmm commented Feb 11, 2020

Mobile app and SFDC are managed by two separate teams, so if I want to change some configuration in SFDC I gotta have enough proof to persuade people, which as you can guess, most mobile developers don't. If we can have a workaround from SDK, many people's life will be easier.

@wmathurin
Copy link
Contributor

I understand. We will fix in a future release.
In the mean time, you can fork the SDK, apply the change above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants