Skip to content

Commit 5433ebb

Browse files
committed
Remove duplicate Create User requests
* If multiple create user requests are enqueued for the same external ID, only keep the most recent one, and remove the previous. * These requests should all have the same identity model since they share external IDs, so only keeping the latest is adequate. * This prevents multiple Create User requests with the same external ID from being executed simultaneously, which is possible when JWT is on, as we allow future logins to be sent before past user's login succeeds. * An example of this is login(a) > login(b) > login(a) > login(b) but user A has an expired token. Once the token is updated for userA, potentially both logins could be executed if we don't prevent duplicates.
1 parent a2420ee commit 5433ebb

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ class OSUserExecutor {
181181
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(model)
182182
}
183183

184+
/// Checks if two requests are creating the same user by external ID
185+
private func isDuplicateCreateUser(_ request: OSRequestCreateUser, _ other: OSUserRequest) -> Bool {
186+
guard let other = other as? OSRequestCreateUser,
187+
request.identityModel.externalId != nil,
188+
other.identityModel.externalId != nil
189+
else {
190+
return false
191+
}
192+
return request.identityModel.externalId == other.identityModel.externalId
193+
}
194+
195+
/// Before enqueueing a Create User request, check for duplicates and remove previous matching duplicates
196+
private func appendCreateUserToQueue(_ request: OSRequestCreateUser) {
197+
self.dispatchQueue.async {
198+
self.userRequestQueue.removeAll(where: { self.isDuplicateCreateUser(request, $0) })
199+
self.userRequestQueue.append(request)
200+
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_USER_EXECUTOR_USER_REQUEST_QUEUE_KEY, withValue: self.userRequestQueue)
201+
}
202+
}
203+
184204
func appendToQueue(_ request: OSUserRequest) {
185205
self.dispatchQueue.async {
186206
self.userRequestQueue.append(request)
@@ -286,8 +306,7 @@ extension OSUserExecutor {
286306
let originalPushToken = user.pushSubscriptionModel.address
287307
let request = OSRequestCreateUser(identityModel: user.identityModel, propertiesModel: user.propertiesModel, pushSubscriptionModel: user.pushSubscriptionModel, originalPushToken: originalPushToken)
288308

289-
appendToQueue(request)
290-
309+
appendCreateUserToQueue(request)
291310
executePendingRequests()
292311
}
293312

@@ -296,7 +315,7 @@ extension OSUserExecutor {
296315
*/
297316
func createUser(aliasLabel: String, aliasId: String, identityModel: OSIdentityModel) {
298317
let request = OSRequestCreateUser(aliasLabel: aliasLabel, aliasId: aliasId, identityModel: identityModel)
299-
appendToQueue(request)
318+
appendCreateUserToQueue(request)
300319
executePendingRequests()
301320
}
302321

0 commit comments

Comments
 (0)