diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml
index ae0e89131..27168bf9b 100644
--- a/Habitica/AndroidManifest.xml
+++ b/Habitica/AndroidManifest.xml
@@ -26,6 +26,7 @@
+
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ResourcesExtensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ResourcesExtensions.kt
index 757066880..4905d7cba 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ResourcesExtensions.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ResourcesExtensions.kt
@@ -3,8 +3,8 @@ package com.habitrpg.android.habitica.extensions
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
-import com.google.firebase.crashlytics.ktx.crashlytics
-import com.google.firebase.ktx.Firebase
+import com.habitrpg.android.habitica.helpers.CrashReporter
+
import com.habitrpg.android.habitica.ui.activities.BaseActivity
import java.util.Locale
@@ -19,7 +19,7 @@ fun Resources.forceLocale(
updateConfiguration(configuration, displayMetrics)
try {
- Firebase.crashlytics.setCustomKey("language", locale.toLanguageTag())
+ CrashReporter.setCustomKey("language", locale.toLanguageTag())
} catch (_: IllegalStateException) {
// issue with getting firebase
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt
index b25eb52f4..a8150f676 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt
@@ -242,12 +242,6 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
"type" to type.name
)
)
- FirebaseAnalytics.getInstance(activity).logEvent(
- "adRewardEarned",
- bundleOf(
- Pair("type", type.name)
- )
- )
rewardAction(true)
}*/
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Analytics.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Analytics.kt
index f5af53090..44a79a9b9 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Analytics.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Analytics.kt
@@ -79,7 +79,8 @@ object Analytics {
Amplitude(
Configuration(
context.getString(R.string.amplitude_app_id),
- context
+ context,
+ optOut = true,
)
)
firebase = FirebaseAnalytics.getInstance(context)
@@ -126,4 +127,14 @@ object Analytics {
fun logException(t: Throwable) {
FirebaseCrashlytics.getInstance().recordException(t)
}
+
+ fun setAnalyticsConsent(consents: Boolean?) {
+ if (consents == true) {
+ firebase.setAnalyticsCollectionEnabled(true)
+ amplitude.configuration.optOut = false
+ } else {
+ firebase.setAnalyticsCollectionEnabled(false)
+ amplitude.configuration.optOut = true
+ }
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/CrashReporter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/CrashReporter.kt
new file mode 100644
index 000000000..72bc974b2
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/CrashReporter.kt
@@ -0,0 +1,14 @@
+package com.habitrpg.android.habitica.helpers
+
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.crashlytics.ktx.crashlytics
+import com.google.firebase.ktx.Firebase
+
+object CrashReporter {
+ fun setCustomKey(key: String, value: String) {
+ Firebase.crashlytics.setCustomKey(key, value)
+ }
+ fun recordException(throwable: Throwable) {
+ Firebase.crashlytics.recordException(throwable)
+ }
+}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt
index 415eda1a3..ba9b2e638 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt
@@ -23,7 +23,6 @@ import com.android.billingclient.api.acknowledgePurchase
import com.android.billingclient.api.consumePurchase
import com.android.billingclient.api.queryProductDetails
import com.android.billingclient.api.queryPurchasesAsync
-import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ApiClient
@@ -122,7 +121,7 @@ class PurchaseHandler(
}
else -> {
- FirebaseCrashlytics.getInstance().recordException(Throwable(result.debugMessage))
+ CrashReporter.recordException(Throwable(result.debugMessage))
}
}
}
@@ -291,7 +290,7 @@ class PurchaseHandler(
}
if (skuDetailsResult.billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Log.e("PurchaseHandler", "Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}")
- FirebaseCrashlytics.getInstance().recordException(
+ CrashReporter.recordException(
Throwable(
"Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}"
)
@@ -496,7 +495,7 @@ class PurchaseHandler(
}
}
processedPurchases.remove(purchase.orderId)
- FirebaseCrashlytics.getInstance().recordException(throwable)
+ CrashReporter.recordException(throwable)
}
suspend fun checkForSubscription(): Purchase? {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt
index 6f91d69bf..02e569dab 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt
@@ -5,8 +5,11 @@ import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.lifecycle.LifecycleCoroutineScope
-import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.R
+import com.habitrpg.android.habitica.helpers.Analytics
+import com.habitrpg.android.habitica.helpers.AnalyticsTarget
+import com.habitrpg.android.habitica.helpers.EventCategory
+import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
@@ -196,10 +199,8 @@ class ShowNotificationInteractor(
}
private fun logOnboardingEvents(type: String) {
- if (User.ONBOARDING_ACHIEVEMENT_KEYS.contains(type)) {
- FirebaseAnalytics.getInstance(activity).logEvent(type, null)
- } else if (type == Notification.Type.ACHIEVEMENT_ONBOARDING_COMPLETE.type) {
- FirebaseAnalytics.getInstance(activity).logEvent(type, null)
+ if (User.ONBOARDING_ACHIEVEMENT_KEYS.contains(type) || type == Notification.Type.ACHIEVEMENT_ONBOARDING_COMPLETE.type) {
+ Analytics.sendEvent(type, EventCategory.BEHAVIOUR, HitType.EVENT, null, AnalyticsTarget.FIREBASE)
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt
index 9195d1b27..9c40fdc61 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt
@@ -45,4 +45,5 @@ open class Preferences : RealmObject(), AvatarPreferences, BaseObject {
var emailNotifications: EmailNotificationsPreference? = null
var autoEquip: Boolean = true
var tasks: UserTaskPreferences? = null
+ var analyticsConsent: Boolean? = null
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
index 4d0398c5e..f0c524d41 100755
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
@@ -46,8 +46,6 @@ import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.gms.wearable.Wearable
-import com.google.firebase.crashlytics.ktx.crashlytics
-import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.FirebasePerformance
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.MainNavDirections
@@ -60,6 +58,7 @@ import com.habitrpg.android.habitica.extensions.hideKeyboard
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
+import com.habitrpg.android.habitica.helpers.CrashReporter
import com.habitrpg.android.habitica.helpers.EventCategory
import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.helpers.NotificationOpenHandler
@@ -644,9 +643,9 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
}
preferences?.sound?.let { soundManager.soundTheme = it }
- val crashlytics = Firebase.crashlytics
- crashlytics.setCustomKey("day_start", user.preferences?.dayStart ?: 0)
- crashlytics.setCustomKey("timezone_offset", user.preferences?.timezoneOffset ?: 0)
+ CrashReporter.setCustomKey("day_start", user.preferences?.dayStart ?: 0)
+ CrashReporter.setCustomKey("timezone_offset", user.preferences?.timezoneOffset ?: 0)
+ Analytics.setAnalyticsConsent(user.preferences?.analyticsConsent)
displayDeathDialogIfNeeded()
YesterdailyDialog.showDialogIfNeeded(this, user.id, userRepository, taskRepository)
@@ -865,7 +864,7 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
errorJob?.cancel()
}
lifecycleScope.launch(Dispatchers.Main) {
- if (binding.content.connectionIssueView.visibility == View.VISIBLE) {
+ if (binding.content.connectionIssueView.isVisible) {
binding.content.connectionIssueView.visibility = View.GONE
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt
index a8e3e625d..dff903e28 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt
@@ -10,7 +10,6 @@ import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.widget.Toast
import androidx.core.net.toUri
-import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.FragmentAboutBinding
import com.habitrpg.android.habitica.helpers.AppConfigManager
@@ -148,7 +147,6 @@ class AboutFragment : BaseMainFragment() {
private fun doTheThing() {
val context = context ?: return
- FirebaseAnalytics.getInstance(context).logEvent("found_easter_egg", null)
DataBindingUtils.loadImage(context, "Pet-Sabretooth-Base") { bitmap ->
mainActivity?.runOnUiThread {
mainActivity?.let {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
index 5c1fb0fee..5f868fad4 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
@@ -19,6 +19,10 @@ import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.extensions.setNavigationBarDarkIcons
+import com.habitrpg.android.habitica.helpers.Analytics
+import com.habitrpg.android.habitica.helpers.AnalyticsTarget
+import com.habitrpg.android.habitica.helpers.EventCategory
+import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.helpers.SoundManager
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
@@ -72,12 +76,13 @@ abstract class BaseMainFragment : BaseFragment() {
showToolbar()
enableToolbarScrolling()
}
- context?.let {
- FirebaseAnalytics.getInstance(it).logEvent(
- "fragment_view",
- bundleOf(Pair("fragment", this::class.java.canonicalName))
- )
- }
+ Analytics.sendEvent(
+ "fragment_view",
+ EventCategory.NAVIGATION,
+ HitType.PAGEVIEW,
+ mapOf("fragment" to (this::class.java.canonicalName ?: "")),
+ AnalyticsTarget.FIREBASE
+ )
return super.onCreateView(inflater, container, savedInstanceState)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt
index 274453401..a191b2684 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt
@@ -15,7 +15,6 @@ import androidx.fragment.app.viewModels
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
-import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding
import com.habitrpg.android.habitica.models.social.Group
@@ -71,12 +70,6 @@ class GuildFragment : BaseMainFragment() {
setViewPagerAdapter()
setFragments()
- if (viewModel.groupID == "f2db2a7f-13c5-454d-b3ee-ea1f5089e601") {
- context?.let {
- FirebaseAnalytics.getInstance(it).logEvent("opened_no_party_guild", null)
- }
- }
-
viewModel.retrieveGroup { }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientGemsDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientGemsDialog.kt
index 6dcfb616f..7c746f440 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientGemsDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientGemsDialog.kt
@@ -7,10 +7,13 @@ import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
-import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.extensions.addCloseButton
+import com.habitrpg.android.habitica.helpers.Analytics
+import com.habitrpg.android.habitica.helpers.AnalyticsTarget
import com.habitrpg.android.habitica.helpers.AppConfigManager
+import com.habitrpg.android.habitica.helpers.EventCategory
+import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.PurchaseTypes
import com.habitrpg.android.habitica.interactors.InsufficientGemsUseCase
@@ -100,9 +103,12 @@ class InsufficientGemsDialog(val parentActivity: Activity, var gemPrice: Int) :
purchaseButton.isVisible = true
purchaseButton?.setOnClickListener {
- FirebaseAnalytics.getInstance(context).logEvent(
+ Analytics.sendEvent(
"purchased_gems_from_insufficient",
- bundleOf(Pair("gemPrice", gemPrice), Pair("sku", ""))
+ EventCategory.BEHAVIOUR,
+ HitType.EVENT,
+ mapOf(Pair("gemPrice", gemPrice), Pair("sku", "")),
+ AnalyticsTarget.FIREBASE
)
MainScope().launchCatching {
insufficientGemsUseCase.callInteractor(
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
index 76e06dc2a..8f53115b7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
@@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.views.shops
import android.app.Activity
import android.content.Context
import android.graphics.drawable.BitmapDrawable
+import android.media.metrics.Event
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
@@ -12,7 +13,6 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
-import com.google.firebase.analytics.FirebaseAnalytics
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
@@ -23,6 +23,7 @@ import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.extensions.getShortRemainingString
import com.habitrpg.android.habitica.helpers.Analytics
+import com.habitrpg.android.habitica.helpers.AnalyticsTarget
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.EventCategory
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
@@ -437,13 +438,16 @@ class PurchaseDialog(
}
private fun buyItem(quantity: Int) {
- FirebaseAnalytics.getInstance(context).logEvent(
+ Analytics.sendEvent(
"item_purchased",
- bundleOf(
- Pair("shop", shopIdentifier),
- Pair("type", shopItem.purchaseType),
- Pair("key", shopItem.key)
- )
+ EventCategory.BEHAVIOUR,
+ HitType.EVENT,
+ mapOf(
+ "shop" to (shopIdentifier ?: ""),
+ "type" to shopItem.purchaseType,
+ "key" to shopItem.key
+ ),
+ AnalyticsTarget.FIREBASE
)
HapticFeedbackManager.tap(buyButton)
val snackbarText = arrayOf("")