Skip to content

Commit b5d37d8

Browse files
authored
Merge pull request #4112 from wmathurin/doc-parent-children-sync-fieldlist-guidance
docs(mobilesync): add fieldlist guidance for SFParentChildrenSyncUpTarget
2 parents 5dd8562 + 8cca56c commit b5d37d8

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

docs/mobilesync/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,59 @@ Max batch size: 1 (one parent + children per request). Uses `@{refId.id}` substi
520520

521521
`isNewerThanServer:` checks parent and all children timestamps in a single SOQL.
522522

523+
#### Fieldlist Configuration
524+
525+
Both the parent and children fieldlists passed to `SFParentChildrenSyncUpTarget` must contain only **user-writable fields**. Salesforce will reject the Composite API request with `INVALID_FIELD_FOR_INSERT_UPDATE` if any of the following system/audit fields are included:
526+
527+
- `Id`
528+
- `CreatedDate`
529+
- `LastModifiedDate`
530+
- `SystemModstamp`
531+
- `IsDeleted`
532+
533+
**The child's `parentIdFieldName` must not appear in `childrenCreateFieldlist`.** When a child record is being created alongside a new parent, the SDK injects the parent reference automatically using `@{refId.id}` substitution in the Composite API request body. This tells Salesforce to resolve the child's lookup field to the server-assigned ID of the just-created parent record. If you also include that field name explicitly in `childrenCreateFieldlist`, the request will contain a conflicting explicit value alongside the reference substitution, and Salesforce will return `INVALID_FIELD_FOR_INSERT_UPDATE`.
534+
535+
The `parentIdFieldName` **may** appear in `childrenUpdateFieldlist` when updating existing child records (where no reference substitution is used), provided the field is user-writable in that context.
536+
537+
**Example — Account (parent) + Contact (child)**
538+
539+
```objc
540+
// CORRECT
541+
SFParentInfo *parentInfo = [SFParentInfo newWithSObjectType:@"Account"
542+
soupName:@"accounts"
543+
idFieldName:@"Id"
544+
modificationDateFieldName:@"LastModifiedDate"
545+
externalIdFieldName:nil];
546+
547+
SFChildrenInfo *childrenInfo = [SFChildrenInfo newWithSObjectType:@"Contact"
548+
soupName:@"contacts"
549+
parentIdFieldName:@"AccountId" // lookup to Account
550+
idFieldName:@"Id"
551+
modificationDateFieldName:@"LastModifiedDate"];
552+
553+
// AccountId is intentionally absent from childrenCreateFieldlist — the SDK substitutes it automatically.
554+
SFParentChildrenSyncUpTarget *target =
555+
[SFParentChildrenSyncUpTarget newSyncTargetWithParentInfo:parentInfo
556+
parentCreateFieldlist:@[@"Name", @"BillingCity"] // no Id, CreatedDate, etc.
557+
parentUpdateFieldlist:@[@"Name", @"BillingCity"]
558+
childrenInfo:childrenInfo
559+
childrenCreateFieldlist:@[@"LastName", @"FirstName"] // AccountId omitted
560+
childrenUpdateFieldlist:@[@"LastName", @"FirstName", @"AccountId"]
561+
relationshipType:SFParentChildrenRelationshipTypeMasterDetail];
562+
563+
// INCORRECT — causes INVALID_FIELD_FOR_INSERT_UPDATE
564+
// childrenCreateFieldlist:@[@"LastName", @"FirstName", @"AccountId"] // AccountId must NOT be here
565+
```
566+
567+
**Summary of rules:**
568+
569+
| Fieldlist | Exclude system fields | Exclude `parentIdFieldName`? |
570+
|---|---|---|
571+
| `parentCreateFieldlist` | Yes (`Id`, `CreatedDate`, `LastModifiedDate`, `SystemModstamp`, `IsDeleted`) | N/A |
572+
| `parentUpdateFieldlist` | Yes | N/A |
573+
| `childrenCreateFieldlist` | Yes | **Yes — always** |
574+
| `childrenUpdateFieldlist` | Yes | No (optional, if user-writable) |
575+
523576
---
524577
525578
## Layout and Metadata Sync

0 commit comments

Comments
 (0)