Skip to content

Commit

Permalink
Added force send properties logic for remote config request (#588)
Browse files Browse the repository at this point in the history
* Added force send properties logic for remote config request

* Fixed checks

---------

Co-authored-by: Surik <[email protected]>
  • Loading branch information
suriksarkisyan and actions-user authored Jun 4, 2024
1 parent 028422d commit fcee318
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 14 deletions.
1 change: 1 addition & 0 deletions config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
<ID>TooManyFunctions:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider</ID>
<ID>TooManyFunctions:QRemoteConfigManager.kt$QRemoteConfigManager</ID>
<ID>TooManyFunctions:QRepository.kt$QRepository</ID>
<ID>TooManyFunctions:QUserPropertiesManager.kt$QUserPropertiesManager : FacebookAttributionListener</ID>
<ID>TooManyFunctions:Qonversion.kt$Qonversion</ID>
<ID>TooManyFunctions:QonversionBillingService.kt$QonversionBillingService : PurchasesUpdatedListenerConnectionListenerBillingService</ID>
<ID>TooManyFunctions:QonversionInternal.kt$QonversionInternal : QonversionLifecycleDelegateAppStateProvider</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.qonversion.android.sdk.dto.QRemoteConfigList
import com.qonversion.android.sdk.dto.QonversionError
import com.qonversion.android.sdk.internal.provider.UserStateProvider
import com.qonversion.android.sdk.internal.services.QRemoteConfigService
import com.qonversion.android.sdk.listeners.QonversionEmptyCallback
import com.qonversion.android.sdk.listeners.QonversionExperimentAttachCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigListCallback
Expand All @@ -31,6 +32,7 @@ internal class QRemoteConfigManager @Inject constructor(
lateinit var userStateProvider: UserStateProvider
private var loadingStates = mutableMapOf<String?, LoadingState>()
private val listRequests = mutableListOf<ListRequestData>()
lateinit var userPropertiesManager: QUserPropertiesManager

fun handlePendingRequests() {
loadingStates.filter { it.value.callbacks.isNotEmpty() }
Expand Down Expand Up @@ -77,14 +79,19 @@ internal class QRemoteConfigManager @Inject constructor(

loadingState.isInProgress = true
loadingState.loadedConfig = null
remoteConfigService.loadRemoteConfig(contextKey, object : QonversionRemoteConfigCallback {
override fun onSuccess(remoteConfig: QRemoteConfig) {
loadingState.loadedConfig = remoteConfig
fireToCallbacks(contextKey) { onSuccess(remoteConfig) }
}

override fun onError(error: QonversionError) {
fireToCallbacks(contextKey) { onError(error) }
userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
override fun onComplete() {
remoteConfigService.loadRemoteConfig(contextKey, object : QonversionRemoteConfigCallback {
override fun onSuccess(remoteConfig: QRemoteConfig) {
loadingState.loadedConfig = remoteConfig
fireToCallbacks(contextKey) { onSuccess(remoteConfig) }
}

override fun onError(error: QonversionError) {
fireToCallbacks(contextKey) { onError(error) }
}
})
}
})
}
Expand All @@ -106,11 +113,15 @@ internal class QRemoteConfigManager @Inject constructor(
return
}

remoteConfigService.loadRemoteConfigs(
contextKeys,
includeEmptyContextKey,
getRemoteConfigListCallbackWrapper(callback),
)
userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
override fun onComplete() {
remoteConfigService.loadRemoteConfigs(
contextKeys,
includeEmptyContextKey,
getRemoteConfigListCallbackWrapper(callback),
)
}
})
}

fun loadRemoteConfigList(callback: QonversionRemoteConfigListCallback) {
Expand All @@ -119,7 +130,11 @@ internal class QRemoteConfigManager @Inject constructor(
return
}

remoteConfigService.loadRemoteConfigs(getRemoteConfigListCallbackWrapper(callback))
userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
override fun onComplete() {
remoteConfigService.loadRemoteConfigs(getRemoteConfigListCallbackWrapper(callback))
}
})
}

fun attachUserToExperiment(experimentId: String, groupId: String, callback: QonversionExperimentAttachCallback) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.qonversion.android.sdk.internal.logger.Logger
import com.qonversion.android.sdk.internal.provider.AppStateProvider
import com.qonversion.android.sdk.internal.repository.QRepository
import com.qonversion.android.sdk.internal.storage.PropertiesStorage
import com.qonversion.android.sdk.listeners.QonversionEmptyCallback
import com.qonversion.android.sdk.listeners.QonversionUserPropertiesCallback
import javax.inject.Inject

Expand All @@ -31,6 +32,7 @@ internal class QUserPropertiesManager @Inject internal constructor(
private var isSendingScheduled = false
private var retryDelay = PROPERTY_UPLOAD_MIN_DELAY
private var retriesCounter = 0
private var completions = mutableListOf<QonversionEmptyCallback>()

companion object {
private const val LOOPER_THREAD_NAME = "userPropertiesThread"
Expand Down Expand Up @@ -67,19 +69,27 @@ internal class QUserPropertiesManager @Inject internal constructor(
setCustomUserProperty(QUserPropertyKey.FacebookAttribution.userPropertyCode, id)
}

fun forceSendProperties() {
public fun forceSendProperties(callback: QonversionEmptyCallback? = null) {
if (isRequestInProgress) {
if (callback != null) {
completions.add(callback)
}
return
}

val properties = propertiesStorage.getProperties()

if (properties.isNotEmpty()) {
if (callback != null) {
completions.add(callback)
}

isRequestInProgress = true
isSendingScheduled = false

repository.sendProperties(properties,
onSuccess = { result ->
fireCallbacks()
result.propertyErrors.forEach { propertyError ->
logger.error("Failed to save property ${propertyError.key}: ${propertyError.error}")
}
Expand All @@ -92,6 +102,7 @@ internal class QUserPropertiesManager @Inject internal constructor(
propertiesStorage.clear(properties)
},
onError = {
fireCallbacks()
isRequestInProgress = false

if (it.code === QonversionErrorCode.InvalidClientUid) {
Expand All @@ -108,9 +119,18 @@ internal class QUserPropertiesManager @Inject internal constructor(
retryPropertiesRequest()
}
})
} else {
callback?.onComplete()
}
}

private fun fireCallbacks() {
val callbacks = completions.toList()
completions.clear()

callbacks.forEach { callback -> callback.onComplete() }
}

@VisibleForTesting
fun retryPropertiesRequest() {
retriesCounter++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ internal class QonversionInternal(
userPropertiesManager.productCenterManager = productCenterManager
userPropertiesManager.sendFacebookAttribution()

remoteConfigManager.userPropertiesManager = userPropertiesManager

val lifecycleHandler = AppLifecycleHandler(this)
postToMainThread { ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleHandler) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,8 @@ interface QonversionUserPropertiesCallback {
fun onSuccess(userProperties: QUserProperties)
fun onError(error: QonversionError)
}

interface QonversionEmptyCallback {

fun onComplete()
}

0 comments on commit fcee318

Please sign in to comment.