-
Notifications
You must be signed in to change notification settings - Fork 367
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1727 from OneSignal/user-model/sdk-migration
[User Model] Support migrating user from SDK 4.x to SDK 5.x
- Loading branch information
Showing
8 changed files
with
211 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
...rc/main/java/com/onesignal/user/internal/operations/LoginUserFromSubscriptionOperation.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.onesignal.user.internal.operations | ||
|
||
import com.onesignal.core.internal.operations.GroupComparisonType | ||
import com.onesignal.core.internal.operations.Operation | ||
import com.onesignal.user.internal.operations.impl.executors.LoginUserFromSubscriptionOperationExecutor | ||
|
||
/** | ||
* An [Operation] to login the user with the [subscriptionId] provided. | ||
*/ | ||
class LoginUserFromSubscriptionOperation() : Operation(LoginUserFromSubscriptionOperationExecutor.LOGIN_USER_FROM_SUBSCRIPTION_USER) { | ||
/** | ||
* The application ID the user will exist/be logged in under. | ||
*/ | ||
var appId: String | ||
get() = getStringProperty(::appId.name) | ||
private set(value) { setStringProperty(::appId.name, value) } | ||
|
||
/** | ||
* The local OneSignal ID this user was initially logged in under. The user models with this ID | ||
* will have its ID updated with the backend-generated ID post-create. | ||
*/ | ||
var onesignalId: String | ||
get() = getStringProperty(::onesignalId.name) | ||
private set(value) { setStringProperty(::onesignalId.name, value) } | ||
|
||
/** | ||
* The optional external ID of this newly logged-in user. Must be unique for the [appId]. | ||
*/ | ||
var subscriptionId: String | ||
get() = getStringProperty(::subscriptionId.name) | ||
private set(value) { setStringProperty(::subscriptionId.name, value) } | ||
|
||
override val createComparisonKey: String get() = "$appId.Subscription.$subscriptionId.Login" | ||
override val modifyComparisonKey: String get() = "$appId.Subscription.$subscriptionId.Login" | ||
override val groupComparisonType: GroupComparisonType = GroupComparisonType.NONE | ||
override val canStartExecute: Boolean = true | ||
|
||
constructor(appId: String, onesignalId: String, playerId: String) : this() { | ||
this.appId = appId | ||
this.onesignalId = onesignalId | ||
this.subscriptionId = playerId | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
...nal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package com.onesignal.user.internal.operations.impl.executors | ||
|
||
import com.onesignal.common.NetworkUtils | ||
import com.onesignal.common.exceptions.BackendException | ||
import com.onesignal.common.modeling.ModelChangeTags | ||
import com.onesignal.core.internal.operations.ExecutionResponse | ||
import com.onesignal.core.internal.operations.ExecutionResult | ||
import com.onesignal.core.internal.operations.IOperationExecutor | ||
import com.onesignal.core.internal.operations.Operation | ||
import com.onesignal.debug.internal.logging.Logging | ||
import com.onesignal.user.internal.backend.ISubscriptionBackendService | ||
import com.onesignal.user.internal.backend.IdentityConstants | ||
import com.onesignal.user.internal.identity.IdentityModelStore | ||
import com.onesignal.user.internal.operations.LoginUserFromSubscriptionOperation | ||
import com.onesignal.user.internal.operations.RefreshUserOperation | ||
import com.onesignal.user.internal.properties.PropertiesModel | ||
import com.onesignal.user.internal.properties.PropertiesModelStore | ||
|
||
internal class LoginUserFromSubscriptionOperationExecutor( | ||
private val _subscriptionBackend: ISubscriptionBackendService, | ||
private val _identityModelStore: IdentityModelStore, | ||
private val _propertiesModelStore: PropertiesModelStore | ||
) : IOperationExecutor { | ||
|
||
override val operations: List<String> | ||
get() = listOf(LOGIN_USER_FROM_SUBSCRIPTION_USER) | ||
|
||
override suspend fun execute(operations: List<Operation>): ExecutionResponse { | ||
Logging.debug("LoginUserFromSubscriptionOperationExecutor(operation: $operations)") | ||
|
||
val startingOp = operations.first() | ||
|
||
if (startingOp is LoginUserFromSubscriptionOperation) { | ||
return loginUser(startingOp) | ||
} | ||
|
||
throw Exception("Unrecognized operation: $startingOp") | ||
} | ||
|
||
private suspend fun loginUser(loginUserOp: LoginUserFromSubscriptionOperation): ExecutionResponse { | ||
try { | ||
val identities = _subscriptionBackend.getIdentityFromSubscription( | ||
loginUserOp.appId, | ||
loginUserOp.subscriptionId | ||
) | ||
val backendOneSignalId = identities.getOrDefault(IdentityConstants.ONESIGNAL_ID, null) | ||
|
||
if (backendOneSignalId == null) { | ||
Logging.warn("Subscription ${loginUserOp.subscriptionId} has no ${IdentityConstants.ONESIGNAL_ID}!") | ||
return ExecutionResponse(ExecutionResult.FAIL_NORETRY) | ||
} | ||
|
||
val idTranslations = mutableMapOf<String, String>() | ||
// Add the "local-to-backend" ID translation to the IdentifierTranslator for any operations that were | ||
// *not* executed but still reference the locally-generated IDs. | ||
// Update the current identity, property, and subscription models from a local ID to the backend ID | ||
idTranslations[loginUserOp.onesignalId] = backendOneSignalId | ||
|
||
val identityModel = _identityModelStore.model | ||
val propertiesModel = _propertiesModelStore.model | ||
|
||
if (identityModel.onesignalId == loginUserOp.onesignalId) { | ||
identityModel.setStringProperty(IdentityConstants.ONESIGNAL_ID, backendOneSignalId, ModelChangeTags.HYDRATE) | ||
} | ||
|
||
if (propertiesModel.onesignalId == loginUserOp.onesignalId) { | ||
propertiesModel.setStringProperty(PropertiesModel::onesignalId.name, backendOneSignalId, ModelChangeTags.HYDRATE) | ||
} | ||
|
||
return ExecutionResponse(ExecutionResult.SUCCESS, idTranslations,listOf(RefreshUserOperation(loginUserOp.appId, backendOneSignalId))) | ||
} catch (ex: BackendException) { | ||
val responseType = NetworkUtils.getResponseStatusType(ex.statusCode) | ||
|
||
return when (responseType) { | ||
NetworkUtils.ResponseStatusType.RETRYABLE -> | ||
ExecutionResponse(ExecutionResult.FAIL_RETRY) | ||
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> | ||
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED) | ||
else -> | ||
ExecutionResponse(ExecutionResult.FAIL_NORETRY) | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
const val LOGIN_USER_FROM_SUBSCRIPTION_USER = "login-user-from-subscription" | ||
} | ||
} |