Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ abstract class Operation(name: String) : Model() {
setStringProperty(::name.name, value)
}

/**
* externalId of the user this operation was enqueued for. Captured at construction
* time so the op stays bound to its original user even if the current user changes
* before the op executes. Null for anonymous users.
*/
var externalId: String?
get() = getOptStringProperty(::externalId.name)
internal set(value) { // `internal` so subclass constructors can assign at construction time
setOptStringProperty(::externalId.name, value)
}
Comment thread
claude[bot] marked this conversation as resolved.

/**
* Whether this operation requires a valid JWT when Identity Verification is active.
* Subclasses may override to `false` for endpoints that don't require auth.
*/
open val requiresJwt: Boolean get() = true

init {
this.name = name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ internal class TrackGooglePurchase(
TrackPurchaseOperation(
_configModelStore.model.appId,
_identityModelStore.model.onesignalId,
_identityModelStore.model.externalId,
newAsExisting,
BigDecimal(0),
purchasesToReport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ internal class SessionListener(

override fun onSessionStarted() {
_propertiesModelStore.model.timezone = TimeUtils.getTimeZoneId()
_operationRepo.enqueue(TrackSessionStartOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId), true)
_operationRepo.enqueue(
TrackSessionStartOperation(
_configModelStore.model.appId,
_identityModelStore.model.onesignalId,
_identityModelStore.model.externalId,
),
true,
)
}

override fun onSessionActive() {
Expand All @@ -60,7 +67,12 @@ internal class SessionListener(
}

_operationRepo.enqueue(
TrackSessionEndOperation(_configModelStore.model.appId, _identityModelStore.model.onesignalId, durationInSeconds),
TrackSessionEndOperation(
_configModelStore.model.appId,
_identityModelStore.model.onesignalId,
_identityModelStore.model.externalId,
durationInSeconds,
),
)

suspendifyOnIO {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class UserSwitcher(
LoginUserFromSubscriptionOperation(
configModel.appId,
identityModelStore.model.onesignalId,
identityModelStore.model.externalId,
legacyPlayerId,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class RebuildUserService(
CreateSubscriptionOperation(
appId,
onesignalId,
identityModel.externalId,
pushSubscription.id,
pushSubscription.type,
pushSubscription.optedIn,
Expand All @@ -60,7 +61,7 @@ class RebuildUserService(
),
)
}
operations.add(RefreshUserOperation(appId, onesignalId))
operations.add(RefreshUserOperation(appId, onesignalId, identityModel.externalId))
return operations
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,10 @@ class CreateSubscriptionOperation() : Operation(SubscriptionOperationExecutor.CR
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, subscriptionId: String, type: SubscriptionType, enabled: Boolean, address: String, status: SubscriptionStatus) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, subscriptionId: String, type: SubscriptionType, enabled: Boolean, address: String, status: SubscriptionStatus) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.subscriptionId = subscriptionId
this.type = type
this.enabled = enabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ class DeleteAliasOperation() : Operation(IdentityOperationExecutor.DELETE_ALIAS)
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, label: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, label: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.label = label
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ class DeleteSubscriptionOperation() : Operation(SubscriptionOperationExecutor.DE
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId) && !IDManager.isLocalId(subscriptionId)
override val applyToRecordId: String get() = subscriptionId

constructor(appId: String, onesignalId: String, subscriptionId: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, subscriptionId: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.subscriptionId = subscriptionId
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ class DeleteTagOperation() : Operation(UpdateUserOperationExecutor.DELETE_TAG) {
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, key: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, key: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.key = key
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class LoginUserFromSubscriptionOperation() : Operation(LoginUserFromSubscription
}

/**
* The optional external ID of this newly logged-in user. Must be unique for the [appId].
* The subscription ID used to look up the user to log in as. Typically a v4 player ID being
* migrated to v5.
*/
var subscriptionId: String
get() = getStringProperty(::subscriptionId.name)
Expand All @@ -42,9 +43,10 @@ class LoginUserFromSubscriptionOperation() : Operation(LoginUserFromSubscription
override val canStartExecute: Boolean = true
override val applyToRecordId: String get() = subscriptionId

constructor(appId: String, onesignalId: String, subscriptionId: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, subscriptionId: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.subscriptionId = subscriptionId
}
Comment thread
claude[bot] marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,6 @@ class LoginUserOperation() : Operation(LoginUserOperationExecutor.LOGIN_USER) {
setStringProperty(::onesignalId.name, value)
}

/**
* The optional external ID of this newly logged-in user. Must be unique for the [appId].
*/
var externalId: String?
get() = getOptStringProperty(::externalId.name)
private set(value) {
setOptStringProperty(::externalId.name, value)
}

/**
* The user ID of an existing user the [externalId] will be attempted to be associated to first.
* When null (or non-null but unsuccessful), a new user will be upserted. This ID *may* be locally generated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class RefreshUserOperation() : Operation(RefreshUserOperationExecutor.REFRESH_US
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
}

override fun translateIds(map: Map<String, String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ class SetAliasOperation() : Operation(IdentityOperationExecutor.SET_ALIAS) {
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, label: String, value: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, label: String, value: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.label = label
this.value = value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ class SetPropertyOperation() : Operation(UpdateUserOperationExecutor.SET_PROPERT
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, property: String, value: Any?) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, property: String, value: Any?) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.property = property
this.value = value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ class SetTagOperation() : Operation(UpdateUserOperationExecutor.SET_TAG) {
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, key: String, value: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, key: String, value: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.key = key
this.value = value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ class TrackCustomEventOperation() : Operation(CustomEventOperationExecutor.CUSTO
setStringProperty(::onesignalId.name, value)
}

/**
* The optional external ID of current logged-in user. Must be unique for the [appId].
*/
var externalId: String?
get() = getOptStringProperty(::externalId.name)
private set(value) {
setOptStringProperty(::externalId.name, value)
}

/**
* The timestamp when the custom event was created.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ class TrackPurchaseOperation() : Operation(UpdateUserOperationExecutor.TRACK_PUR
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, treatNewAsExisting: Boolean, amountSpent: BigDecimal, purchases: List<PurchaseInfo>) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, treatNewAsExisting: Boolean, amountSpent: BigDecimal, purchases: List<PurchaseInfo>) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.treatNewAsExisting = treatNewAsExisting
this.amountSpent = amountSpent
this.purchases = purchases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ class TrackSessionEndOperation() : Operation(UpdateUserOperationExecutor.TRACK_S
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String, sessionTime: Long) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, sessionTime: Long) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.sessionTime = sessionTime
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ class TrackSessionStartOperation() : Operation(UpdateUserOperationExecutor.TRACK
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
override val applyToRecordId: String get() = onesignalId

constructor(appId: String, onesignalId: String) : this() {
constructor(appId: String, onesignalId: String, externalId: String?) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
}

override fun translateIds(map: Map<String, String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ class TransferSubscriptionOperation() : Operation(SubscriptionOperationExecutor.
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId) && !IDManager.isLocalId(subscriptionId)
override val applyToRecordId: String get() = subscriptionId

constructor(appId: String, subscriptionId: String, onesignalId: String) : this() {
constructor(appId: String, subscriptionId: String, onesignalId: String, externalId: String?) : this() {
this.appId = appId
this.subscriptionId = subscriptionId
this.onesignalId = onesignalId
this.externalId = externalId
}

override fun translateIds(map: Map<String, String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ class UpdateSubscriptionOperation() : Operation(SubscriptionOperationExecutor.UP
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId) && !IDManager.isLocalId(subscriptionId)
override val applyToRecordId: String get() = subscriptionId

constructor(appId: String, onesignalId: String, subscriptionId: String, type: SubscriptionType, enabled: Boolean, address: String, status: SubscriptionStatus) : this() {
constructor(appId: String, onesignalId: String, externalId: String?, subscriptionId: String, type: SubscriptionType, enabled: Boolean, address: String, status: SubscriptionStatus) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.externalId = externalId
this.subscriptionId = subscriptionId
this.type = type
this.enabled = enabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ internal class LoginUserFromSubscriptionOperationExecutor(
return ExecutionResponse(
ExecutionResult.SUCCESS,
idTranslations,
listOf(RefreshUserOperation(loginUserOp.appId, backendOneSignalId)),
listOf(RefreshUserOperation(loginUserOp.appId, backendOneSignalId, loginUserOp.externalId)),
)
} catch (ex: BackendException) {
val responseType = NetworkUtils.getResponseStatusType(ex.statusCode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ internal class LoginUserOperationExecutor(
SetAliasOperation(
loginUserOp.appId,
loginUserOp.existingOnesignalId!!,
loginUserOp.externalId,
IdentityConstants.EXTERNAL_ID,
loginUserOp.externalId!!,
),
Expand Down Expand Up @@ -223,7 +224,7 @@ internal class LoginUserOperationExecutor(
val wasPossiblyAnUpsert = identities.isNotEmpty()
val followUpOperations =
if (wasPossiblyAnUpsert) {
listOf(RefreshUserOperation(createUserOperation.appId, backendOneSignalId))
listOf(RefreshUserOperation(createUserOperation.appId, backendOneSignalId, createUserOperation.externalId))
} else {
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ internal class SubscriptionOperationExecutor(
CreateSubscriptionOperation(
lastOperation.appId,
lastOperation.onesignalId,
lastOperation.externalId,
lastOperation.subscriptionId,
lastOperation.type,
lastOperation.enabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ internal class IdentityModelStoreListener(
newValue: Any?,
): Operation {
return if (newValue != null && newValue is String) {
SetAliasOperation(_configModelStore.model.appId, model.onesignalId, property, newValue)
SetAliasOperation(_configModelStore.model.appId, model.onesignalId, model.externalId, property, newValue)
} else {
DeleteAliasOperation(_configModelStore.model.appId, model.onesignalId, property)
DeleteAliasOperation(_configModelStore.model.appId, model.onesignalId, model.externalId, property)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.onesignal.core.internal.config.ConfigModelStore
import com.onesignal.core.internal.operations.IOperationRepo
import com.onesignal.core.internal.operations.Operation
import com.onesignal.core.internal.operations.listeners.SingletonModelStoreListener
import com.onesignal.user.internal.identity.IdentityModelStore
import com.onesignal.user.internal.operations.DeleteTagOperation
import com.onesignal.user.internal.operations.SetPropertyOperation
import com.onesignal.user.internal.operations.SetTagOperation
Expand All @@ -14,6 +15,7 @@ internal class PropertiesModelStoreListener(
store: PropertiesModelStore,
opRepo: IOperationRepo,
private val _configModelStore: ConfigModelStore,
private val _identityModelStore: IdentityModelStore,
) : SingletonModelStoreListener<PropertiesModel>(store, opRepo) {
override fun getReplaceOperation(model: PropertiesModel): Operation? {
// when the property model is replaced, nothing to do on the backend. Already handled via login process.
Expand All @@ -36,14 +38,15 @@ internal class PropertiesModelStoreListener(
return null
}

val externalId = _identityModelStore.model.externalId
if (path.startsWith(PropertiesModel::tags.name)) {
return if (newValue != null && newValue is String) {
SetTagOperation(_configModelStore.model.appId, model.onesignalId, property, newValue)
SetTagOperation(_configModelStore.model.appId, model.onesignalId, externalId, property, newValue)
} else {
DeleteTagOperation(_configModelStore.model.appId, model.onesignalId, property)
DeleteTagOperation(_configModelStore.model.appId, model.onesignalId, externalId, property)
}
}

return SetPropertyOperation(_configModelStore.model.appId, model.onesignalId, property, newValue)
return SetPropertyOperation(_configModelStore.model.appId, model.onesignalId, externalId, property, newValue)
}
}
Loading
Loading