Skip to content

Commit c5477ff

Browse files
committed
UserStorageRefactoring: Removed userId and deviceId usage from Storage and related classes
Removed userId and deviceId properties from Storage interface and their implementation in SharedPreferencesStorage, and removed references to them in ApphudInternal and UserRepository. Now user IDs are taken only from ApphudUser, which simplifies storage logic and prevents data duplication. This is a preparatory stage for further refactoring of work with users.
1 parent 0f7f493 commit c5477ff

File tree

4 files changed

+34
-74
lines changed

4 files changed

+34
-74
lines changed

sdk/src/main/java/com/apphud/sdk/ApphudInternal.kt

Lines changed: 30 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import kotlinx.coroutines.launch
3939
import kotlinx.coroutines.runBlocking
4040
import kotlinx.coroutines.suspendCancellableCoroutine
4141
import kotlinx.coroutines.sync.Mutex
42+
import kotlinx.coroutines.sync.withLock
4243
import kotlinx.coroutines.withContext
4344
import java.util.UUID
4445
import kotlin.coroutines.resume
@@ -109,9 +110,7 @@ internal object ApphudInternal {
109110
internal var didRegisterCustomerAtThisLaunch = false
110111
private var isNew = true
111112
private lateinit var apiKey: ApiKey
112-
lateinit var deviceId: DeviceId
113113
internal var fallbackMode = false
114-
internal lateinit var userId: UserId
115114
internal lateinit var context: Context
116115
internal val userRepository: UserRepository by lazy {
117116
ServiceLocator.instance.userRepository
@@ -222,41 +221,33 @@ internal object ApphudInternal {
222221
val cachedPlacements = if (ignoreCache || !isValid || observerMode) null else readPlacementsFromCache()
223222
val cachedGroups = if (isValid) readGroupsFromCache() else mutableListOf()
224223
val cachedDeviceId = ServiceLocator.instance.sharedPreferencesStorage.deviceId
225-
val cachedUserId = ServiceLocator.instance.sharedPreferencesStorage.userId
226224

227225
sdkLaunchedAt = System.currentTimeMillis()
228226

229227
val generatedUUID = UUID.randomUUID().toString()
230228

231-
val newUserId =
232-
if (inputUserId.isNullOrBlank()) {
233-
cachedUserId ?: generatedUUID
234-
} else {
235-
inputUserId
236-
}
237-
val newDeviceId =
238-
if (inputDeviceId.isNullOrBlank()) {
239-
cachedDeviceId ?: generatedUUID
240-
} else {
241-
inputDeviceId
242-
}
243-
244-
val credentialsChanged = cachedUserId != newUserId || cachedDeviceId != newDeviceId
229+
val newUserId = if (inputUserId.isNullOrBlank()) {
230+
cachedUser?.userId ?: generatedUUID
231+
} else {
232+
inputUserId
233+
}
245234

246-
if (credentialsChanged) {
247-
ServiceLocator.instance.sharedPreferencesStorage.userId = newUserId
248-
ServiceLocator.instance.sharedPreferencesStorage.deviceId = newDeviceId
235+
val newDeviceId = if (inputDeviceId.isNullOrBlank()) {
236+
cachedDeviceId ?: generatedUUID
237+
} else {
238+
inputDeviceId
249239
}
250240

241+
val credentialsChanged = cachedUser?.userId != newUserId || cachedDeviceId != newDeviceId
242+
251243
/**
252244
* We cannot get paywalls and placements from paying current user,
253245
* because paying currentUser doesn't have cache timeout because it has
254246
* purchases history
255247
*
256248
* But paywalls and placements must have cache timeout
257249
*/
258-
this.userId = newUserId
259-
this.deviceId = newDeviceId
250+
ServiceLocator.instance.sharedPreferencesStorage.deviceId = newDeviceId
260251
this.productGroups = cachedGroups
261252
cachedPaywalls?.let { this.paywalls = it }
262253
cachedPlacements?.let { this.placements = it }
@@ -274,13 +265,13 @@ internal object ApphudInternal {
274265
val ruleController = ServiceLocator.instance.ruleController
275266
if (needRegistration) {
276267
isRegisteringUser = true
277-
registration(true) { u, e ->
268+
registration(true) { _, _ ->
278269
if (shouldLoadProducts()) {
279270
loadProducts()
280271
}
281272
coroutineScope.launch {
282273
fetchNativePurchases()
283-
ruleController.start(deviceId)
274+
ruleController.start(newUserId)
284275
}
285276
}
286277
} else {
@@ -291,7 +282,7 @@ internal object ApphudInternal {
291282
}
292283
coroutineScope.launch {
293284
fetchNativePurchases()
294-
ruleController.start(deviceId)
285+
ruleController.start(newUserId)
295286
}
296287
}
297288
}
@@ -402,7 +393,7 @@ internal object ApphudInternal {
402393
}
403394
coroutineScope.launch {
404395
val userIdChanged = ServiceLocator.instance.updateCustomerUseCase(it)
405-
396+
406397
if (userIdChanged) {
407398
mainScope.launch {
408399
apphudListener?.apphudDidChangeUserID(it.userId)
@@ -577,43 +568,18 @@ internal object ApphudInternal {
577568

578569
private val mutex = Mutex()
579570

580-
private fun registration(
571+
private suspend fun registration(
581572
forceRegistration: Boolean = false,
582-
completionHandler: ((ApphudUser?, ApphudError?) -> Unit)?,
583-
) {
584-
coroutineScope.launch(errorHandler) {
585-
val shouldUnlockMutex =
586-
(currentUser == null || currentUser?.isTemporary == true || forceRegistration) && offeringsPreparedCallbacks.isNotEmpty() && !isRegisteringUser && mutex.isLocked
587-
if (shouldUnlockMutex) {
588-
try {
589-
ApphudLog.log("Unlocking the mutex")
590-
mutex.unlock()
591-
} catch (e: Exception) {
592-
ApphudLog.log("Failed to unlock the mutex, force registration")
593-
runCatchingCancellable { startRegistrationCall(forceRegistration) }
594-
.onSuccess { completionHandler?.invoke(it, null) }
595-
.onFailure { completionHandler?.invoke(null, it.toApphudError()) }
596-
}
597-
}
598-
mutex.lock()
599-
try {
600-
if (currentUser == null || forceRegistration) {
601-
runCatchingCancellable { startRegistrationCall(forceRegistration) }
602-
.onSuccess { completionHandler?.invoke(it, null) }
603-
.onFailure { completionHandler?.invoke(null, it.toApphudError()) }
604-
} else {
605-
mainScope.launch {
606-
isRegisteringUser = false
607-
completionHandler?.invoke(currentUser, null)
608-
}
609-
}
610-
} finally {
611-
if (mutex.isLocked) {
612-
mutex.unlock()
613-
}
573+
): ApphudUser =
574+
mutex.withLock {
575+
val cached = userRepository.getCurrentUser()
576+
if (cached != null && !forceRegistration) {
577+
return@withLock cached
614578
}
579+
580+
runCatchingCancellable { startRegistrationCall(forceRegistration) }
581+
.getOrElse { throw it.toApphudError() }
615582
}
616-
}
617583

618584
private suspend fun startRegistrationCall(
619585
forceRegistration: Boolean = false,
@@ -889,7 +855,8 @@ internal object ApphudInternal {
889855
.fold(
890856
onSuccess = { userProperties ->
891857
if (userProperties.success) {
892-
val propertiesInStorage = ServiceLocator.instance.sharedPreferencesStorage.properties
858+
val propertiesInStorage =
859+
ServiceLocator.instance.sharedPreferencesStorage.properties
893860
sentPropertiesForSave.forEach {
894861
propertiesInStorage?.put(it.key, it)
895862
}
@@ -988,7 +955,8 @@ internal object ApphudInternal {
988955
callback?.invoke(false)
989956
} ?: run {
990957
coroutineScope.launch(errorHandler) {
991-
val grantPromotionalResult = RequestManager.grantPromotional(daysCount, productId, permissionGroup)
958+
val grantPromotionalResult =
959+
RequestManager.grantPromotional(daysCount, productId, permissionGroup)
992960
withContext(Dispatchers.Main) {
993961
grantPromotionalResult
994962
.onSuccess {

sdk/src/main/java/com/apphud/sdk/internal/data/local/UserRepository.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.apphud.sdk.storage.Storage
55
import kotlinx.coroutines.flow.MutableSharedFlow
66
import kotlinx.coroutines.flow.SharedFlow
77
import kotlinx.coroutines.flow.asSharedFlow
8+
import kotlinx.coroutines.flow.firstOrNull
89
import kotlinx.coroutines.sync.Mutex
910
import kotlinx.coroutines.sync.withLock
1011

@@ -23,14 +24,14 @@ internal class UserRepository(
2324

2425
suspend fun getCurrentUser(): ApphudUser? {
2526
return userMutex.withLock {
26-
_currentUser.replayCache.first()
27+
_currentUser.firstOrNull()
2728
}
2829
}
2930

3031
suspend fun updateUser(user: ApphudUser) {
3132
userMutex.withLock {
3233
storage.apphudUser = user
33-
user.let { storage.userId = it.userId }
34+
// user.let { storage.userId = it.userId }
3435
_currentUser.tryEmit(user)
3536
}
3637
}
@@ -39,7 +40,7 @@ internal class UserRepository(
3940
suspend fun clearUser() {
4041
userMutex.withLock {
4142
storage.apphudUser = null
42-
storage.userId = null
43+
// storage.userId = null
4344
_currentUser.tryEmit(null)
4445
}
4546
}

sdk/src/main/java/com/apphud/sdk/storage/SharedPreferencesStorage.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,6 @@ internal class SharedPreferencesStorage(context: Context) : Storage {
3030
.serializeNulls().create()
3131
private val parser: Parser = GsonParser(gson)
3232

33-
override var userId: String?
34-
get() = preferences.getString(USER_ID_KEY, null)
35-
set(value) {
36-
preferences.edit {
37-
putString(USER_ID_KEY, value)
38-
}
39-
}
40-
4133
override var apphudUser: ApphudUser?
4234
get() {
4335
val source = preferences.getString(APPHUD_USER_KEY, null)

sdk/src/main/java/com/apphud/sdk/storage/Storage.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import com.apphud.sdk.domain.FacebookInfo
1111

1212
internal interface Storage {
1313
var lastRegistration: Long
14-
var userId: String?
1514
var deviceId: String?
1615
var apphudUser: ApphudUser?
1716
var deviceIdentifiers: Array<String>

0 commit comments

Comments
 (0)