0

I'm using Salesforce Mobile SDK 12.2.0 in a React Native app and trying to sync up records using an External ID (Delivery_Id__c) to prevent duplicates. However, I'm still seeing duplicate records in Salesforce when syncing up.

This seems to be happening when the initial sync-up fails due to network issues. The record is sent to Salesforce, but the sync-up returns an error, and SmartStore is not updated. Mobile SDK retries the sync when the device regains connectivity, leading to duplicates.

What I Have Done- Configured SyncUp to Use External ID

await syncUp( false, // User store { androidImpl: "com.salesforce.androidsdk.mobilesync.target.ParentChildrenSyncUpTarget", createFieldlist: ["Delivery_Id__c", "Start__c", "End__c", "Driver__c", "Status__c", "Signature__c", "Signer_Name__c", "Account__c", "Vehicle__c"], updateFieldlist: ["Start__c", "Driver__c", "Status__c", "Signature__c", "Signer_Name__c", "Account__c", "Vehicle__c"], parent: { idFieldName: "Id", sobjectType: "Delivery__c", modificationDateFieldName: "LastModifiedDate", externalIdFieldName: "Delivery_Id__c", // External ID soupName: "Delivery__c", }, children: { parentIdFieldName: "Delivery__c", idFieldName: "Id", sobjectType: "Delivery_Item__c", modificationDateFieldName: "LastModifiedDate", externalIdFieldName: "Item_Id__c", soupName: "Delivery_Item__c", sobjectTypePlural: "Delivery_items__r", }, relationshipType: "MASTER_DETAIL", }, "Delivery__c", { mergeMode: mobilesync.MERGE_MODE.LEAVE_IF_CHANGED } ); 

Error Logs (External ID is set to unique)

{ "message": "duplicate value found: Delivery_Id__c duplicates value on record with id: a0tQy000008BZp4IAG", "errorCode": "DUPLICATE_VALUE" } 

This indicates that Salesforce is treating the sync as a create instead of an upsert, even though externalIdFieldName is set. What I Expected - Upsert behavior should find the record by Delivery_Id__c and update it, not create a duplicate.

After sync, local records should be updated with the Salesforce ID.

What’s Actually Happening Some records are created as duplicates instead of being updated.

Questions Am I missing anything in my sync configuration? Why does Mobile SDK still create duplicates even with externalIdFieldName set? Is this a known issue with Salesforce Mobile SDK 13.0.0? How do I ensure that SmartStore correctly updates the record ID after a sync-up?

Here is my smartstore setup

// Fields for Delivery soup const deliveryFields = [ { path: "Id", type: "string" }, { path: "Delivery_Id__c", type: "string" }, { path: "Start__c", type: "string" }, { path: "Driver__c", type: "string" }, { path: "Status__c", type: "string" }, { path: "Signature__c", type: "string" }, { path: "Signer_Name__c", type: "string" }, { path: "Account__c", type: "string" }, { path: "Account_Name__c", type: "string" }, { path: "BillingStreet", type: "string" }, { path: "Billing_City__c", type: "string" }, { path: "Billing_Postalcode__c", type: "string" }, { path: "Vehicle__c", type: "string" }, { path: "Shift__c", type: "string" }, { path: "__local__", type: "string" }, { path: "__locally_created__", type: "string" }, { path: "__locally_updated__", type: "string" }, { path: "__locally_deleted__", type: "string" }, { path: "_soupEntryId", type: "string" }, { path: "__sync_id__", type: "string" }, { path: "__last_error__", type: "string" }, ]; // Fields for Delivery Item soup const deliveryItemFields = [ { path: "Id", type: "string" }, { path: "Item_Id__c", type: "string" }, { path: "Delivery__c", type: "string" }, { path: "Product__c", type: "string" }, { path: "Quantity__c", type: "integer" }, { path: "__local__", type: "string" }, { path: "__locally_created__", type: "string" }, { path: "__locally_updated__", type: "string" }, { path: "__locally_deleted__", type: "string" }, { path: "_soupEntryId", type: "string" }, { path: "__sync_id__", type: "string" }, { path: "__last_error__", type: "string" }, ]; 

And here is what I add to smartstore

 const deliveryData = { Delivery_Id__c: `local_${Date.now()}`, // Temporary ID for SmartStore Id: `Id${Date.now()}`, // Temporary ID for SmartStore Status__c: status, Account__c: selectedAccount.Id, Driver__c: driver.id, Start__c: deliveryDate.toISOString(), End__c: endDate.toISOString(), Account_Name__c: selectedAccount.Name, BillingStreet: selectedAccount.BillingStreet, Billing_City__c: selectedAccount.BillingCity, Billing_Postalcode__c: selectedAccount.BillingPostalCode, __local__: 'true', __locally_created__: 'true', __locally_updated__: 'false', __locally_deleted__: 'false', attributes: { type: "Delivery__c" }, }; // Include signature and signer name if applicable if (status === 'Complete') { deliveryData.Signature__c = `<img src="${signature}" alt="Signature" />`; deliveryData.Signer_Name__c = name.trim(); } console.log('Delivery Payload:', deliveryData); // ✅ 🚀 Close page immediately before saving navigation.goBack(); // Save the delivery to SmartStore smartstore.upsertSoupEntries( false, // Don't use global store 'Delivery__c', // Soup name [deliveryData], // Entries to upsert (result) => { console.log('Successfully saved delivery to SmartStore:', result); // Save delivery items to SmartStore const deliveryItemsPayload = deliveryItems.map((item, index) => ({ Item_Id__c: `local_item_${Date.now()}_${index}`, //Id: `local_item_${Date.now()}_${index}`, Delivery__c: deliveryData.Delivery_Id__c, Product__c: item.product, Quantity__c: parseFloat(item.quantity), __local__: 'true', __locally_created__: 'true', __locally_updated__: 'false', __locally_deleted__: 'false', attributes: { type: "Delivery_Item__c" }, })); smartstore.upsertSoupEntries( false, 'Delivery_Item__c', deliveryItemsPayload, (itemResult) => { markDeliveryUnsynced(); console.log('Successfully saved delivery items to SmartStore:', itemResult); DeliveryEventEmitter.emit('REFRESH_DELIVERIES', { refresh: true }); }, (error) => { console.error('Error saving delivery items to SmartStore:', error); } ); }, (error) => { console.error('Error saving delivery to SmartStore:', error); } ); 
1
  • Fixed it! I was prefixing my external Id's with 'local__' and I had my external Ids in createFieldlist, updateFieldlist, childrenCreateFieldlist and childrenUpdateFieldlist. That fixed the issue ! Commented Feb 6 at 18:18

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.