Skip to content

Commit 9f8e690

Browse files
MuniekMg5d
andauthored
fix(DataStore): created and deleted model on one device appears as created on the other (#3554)
* fix(DataStore): created and deleted model on one device appears as created on the other (#3553) * fix(DataStore): created and deleted model on one device appears as created on the other #3553 Co-authored-by: Di Wu <github@wudi.me> * fix(DataStore): created and deleted model on one device appears as created on the other #3553 --------- Co-authored-by: Di Wu <github@wudi.me>
1 parent c49d836 commit 9f8e690

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/SubscriptionSync/ReconcileAndLocalSave/RemoteSyncReconciler.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,41 @@ struct RemoteSyncReconciler {
3333
}
3434
}
3535

36-
3736
/// Reconciles the incoming `remoteModels` against the local metadata to get the disposition
3837
///
38+
/// GroupBy the remoteModels by model identifier and apply only the latest version of the remoteModel
39+
///
3940
/// - Parameters:
4041
/// - remoteModels: models retrieved from the remote store
4142
/// - localMetadatas: metadata retrieved from the local store
4243
/// - Returns: disposition of models to apply locally
43-
static func getDispositions(_ remoteModels: [RemoteModel],
44-
localMetadatas: [LocalMetadata]) -> [Disposition] {
45-
guard !remoteModels.isEmpty else {
44+
static func getDispositions(
45+
_ remoteModels: [RemoteModel],
46+
localMetadatas: [LocalMetadata]
47+
) -> [Disposition] {
48+
let remoteModelsGroupByIdentifier = remoteModels.reduce([String: [RemoteModel]]()) {
49+
$0.merging([
50+
$1.model.identifier: ($0[$1.model.identifier] ?? []) + [$1]
51+
], uniquingKeysWith: { $1 })
52+
}
53+
54+
let optimizedRemoteModels = remoteModelsGroupByIdentifier.values.compactMap {
55+
$0.sorted(by: { $0.syncMetadata.version > $1.syncMetadata.version }).first
56+
}
57+
58+
guard !optimizedRemoteModels.isEmpty else {
4659
return []
4760
}
48-
61+
4962
guard !localMetadatas.isEmpty else {
50-
return remoteModels.compactMap { getDisposition($0, localMetadata: nil) }
63+
return optimizedRemoteModels.compactMap { getDisposition($0, localMetadata: nil) }
5164
}
52-
53-
let metadataBymodelId = localMetadatas.reduce(into: [:]) { $0[$1.modelId] = $1 }
54-
let dispositions = remoteModels.compactMap { getDisposition($0, localMetadata: metadataBymodelId[$0.model.identifier]) }
55-
65+
66+
let metadataByModelId = localMetadatas.reduce(into: [:]) { $0[$1.modelId] = $1 }
67+
let dispositions = optimizedRemoteModels.compactMap {
68+
getDisposition($0, localMetadata: metadataByModelId[$0.model.identifier])
69+
}
70+
5671
return dispositions
5772
}
5873

AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/SubscriptionSync/RemoteSyncReconcilerTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,33 @@ class RemoteSyncReconcilerTests: XCTestCase {
179179
}
180180
waitForExpectations(timeout: 1)
181181
}
182+
183+
func testGetDispositions_emptyLocal_singleModelAddedAndDeleted() {
184+
let sameId = UUID().uuidString
185+
186+
let remoteModels = [
187+
makeRemoteModel(modelId: sameId, deleted: false, version: 1),
188+
makeRemoteModel(modelId: sameId, deleted: true, version: 2)
189+
]
190+
191+
let dispositions = RemoteSyncReconciler.getDispositions(remoteModels, localMetadatas: [])
192+
193+
XCTAssertTrue(dispositions.isEmpty)
194+
}
195+
196+
func testGetDispositions_emptyLocal_oneModelAdded_SecondModelAddedAndDeleted() {
197+
let sameId = UUID().uuidString
198+
199+
let remoteModels = [
200+
makeRemoteModel(deleted: false, version: 1),
201+
makeRemoteModel(modelId: sameId, deleted: false, version: 1),
202+
makeRemoteModel(modelId: sameId, deleted: true, version: 2)
203+
]
204+
205+
let dispositions = RemoteSyncReconciler.getDispositions(remoteModels, localMetadatas: [])
206+
207+
XCTAssertTrue(dispositions.count == 1)
208+
}
182209

183210
// MARK: - Utilities
184211

0 commit comments

Comments
 (0)