-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* App Analytics Implementation * PR feedback * Remove unused imports
- Loading branch information
1 parent
e9d52fc
commit b5dea14
Showing
7 changed files
with
239 additions
and
6 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
96 changes: 96 additions & 0 deletions
96
android/app-newm/src/main/java/io/newm/utils/AndroidNewmAppAnalyticsTracker.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,96 @@ | ||
package io.newm.utils | ||
|
||
import androidx.core.os.bundleOf | ||
import com.google.firebase.analytics.FirebaseAnalytics | ||
import com.google.firebase.analytics.ktx.analytics | ||
import com.google.firebase.analytics.logEvent | ||
import com.google.firebase.ktx.Firebase | ||
import io.newm.shared.AppAnalyticsTracker | ||
import io.newm.shared.NewmAppLogger | ||
|
||
/** | ||
* Implementation of [AppAnalyticsTracker] for Android using Firebase Analytics. | ||
*/ | ||
class AndroidNewmAppAnalyticsTracker(val logger: NewmAppLogger) : AppAnalyticsTracker { | ||
|
||
private val firebaseAnalytics = Firebase.analytics | ||
|
||
companion object { | ||
private const val MAX_EVENT_NAME_LENGTH = | ||
32 // Firebase allows 40, but using 32 for readability | ||
private const val TAG = "AnalyticsTracker" // Tag for logging | ||
} | ||
|
||
override fun trackEvent(eventName: String, properties: Map<String, Any?>?) { | ||
val safeEventName = validateEventName(eventName) | ||
if (safeEventName == null) { | ||
logger.info(TAG, "Invalid event name: $eventName. Event not tracked.") | ||
return | ||
} | ||
val bundle = bundleOf(*properties?.toList()?.toTypedArray().orEmpty()) | ||
firebaseAnalytics.logEvent(safeEventName, bundle) | ||
} | ||
|
||
override fun trackScreenView(screenName: String) { | ||
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) { | ||
param(FirebaseAnalytics.Param.SCREEN_NAME, screenName) | ||
param(FirebaseAnalytics.Param.SCREEN_CLASS, screenName) // Optional, if relevant | ||
} | ||
} | ||
|
||
override fun setUserId(userId: String) { | ||
firebaseAnalytics.setUserId(userId) | ||
} | ||
|
||
override fun setUserProperty(name: String, value: String) { | ||
firebaseAnalytics.setUserProperty(name, value) | ||
} | ||
|
||
override fun trackScroll(startPosition: Int, endPosition: Int, screenName: String) { | ||
trackEvent( | ||
"scroll", mapOf( | ||
"scroll_position_start" to startPosition, | ||
"scroll_position_end" to endPosition, | ||
"screen_name" to screenName | ||
) | ||
) | ||
} | ||
|
||
override fun trackButtonInteraction(buttonName: String, eventType: String) { | ||
trackEvent(eventType, mapOf("button_name" to buttonName)) | ||
} | ||
|
||
override fun trackPlayButtonClick(songId: String, songName: String) { | ||
trackEvent( | ||
"play_button_click", mapOf( | ||
"song_id" to songId, | ||
"song_name" to songName | ||
) | ||
) | ||
} | ||
|
||
override fun trackAppLaunch() { | ||
trackEvent("app_launch", null) | ||
} | ||
|
||
override fun trackAppClose() { | ||
trackEvent("app_close", null) | ||
} | ||
|
||
override fun trackUserScroll(percentage: Double) { | ||
trackEvent("user_scroll", mapOf("scroll_percentage" to percentage)) | ||
} | ||
|
||
private fun validateEventName(name: String): String? { | ||
if (name.startsWith("firebase_") || name.startsWith("google_") || name.startsWith("ga_")) { | ||
return null | ||
} | ||
|
||
val cleanedName = name.replace(Regex("[^A-Za-z0-9_]"), "_") | ||
return if (cleanedName.length > MAX_EVENT_NAME_LENGTH) { | ||
cleanedName.substring(0, MAX_EVENT_NAME_LENGTH) | ||
} else { | ||
cleanedName | ||
} | ||
} | ||
} |
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
79 changes: 79 additions & 0 deletions
79
shared/src/commonMain/kotlin/io.newm.shared/AppAnalyticsTracker.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,79 @@ | ||
package io.newm.shared | ||
|
||
/** | ||
* Interface for tracking analytics events in the application. | ||
*/ | ||
interface AppAnalyticsTracker { | ||
|
||
/** | ||
* Tracks a custom event with the given name and properties. | ||
* | ||
* @param eventName The name of the event to track. | ||
* @param properties A map of properties associated with the event. | ||
*/ | ||
fun trackEvent(eventName: String, properties: Map<String, Any?>?) | ||
|
||
/** | ||
* Tracks a screen view event. | ||
* | ||
* @param screenName The name of the screen being viewed. | ||
*/ | ||
fun trackScreenView(screenName: String) | ||
|
||
/** | ||
* Sets the user ID for tracking purposes. | ||
* | ||
* @param userId The ID of the user. | ||
*/ | ||
fun setUserId(userId: String) | ||
|
||
/** | ||
* Sets a user property. | ||
* | ||
* @param name The name of the property. | ||
* @param value The value of the property. | ||
*/ | ||
fun setUserProperty(name: String, value: String) | ||
|
||
/** | ||
* Tracks a scroll event. | ||
* | ||
* @param startPosition The starting position of the scroll. | ||
* @param endPosition The ending position of the scroll. | ||
* @param screenName The name of the screen where the scroll happened. | ||
*/ | ||
fun trackScroll(startPosition: Int, endPosition: Int, screenName: String) | ||
|
||
/** | ||
* Tracks a button interaction event. | ||
* | ||
* @param buttonName The name of the button being interacted with. | ||
* @param eventType The type of the event (default is "button_click"). | ||
*/ | ||
fun trackButtonInteraction(buttonName: String, eventType: String = "button_click") | ||
|
||
/** | ||
* Tracks a play button click event with song details. | ||
* | ||
* @param songId The ID of the song being played. | ||
* @param songName The name of the song being played. | ||
*/ | ||
fun trackPlayButtonClick(songId: String, songName: String) | ||
|
||
/** | ||
* Tracks the app launch event. | ||
*/ | ||
fun trackAppLaunch() | ||
|
||
/** | ||
* Tracks the app close event. | ||
*/ | ||
fun trackAppClose() | ||
|
||
/** | ||
* Tracks a user scroll event with a scroll percentage. | ||
* | ||
* @param percentage The percentage of the scroll. | ||
*/ | ||
fun trackUserScroll(percentage: Double) | ||
} |
50 changes: 50 additions & 0 deletions
50
shared/src/commonMain/kotlin/io.newm.shared/NewmAppAnalyticsTracker.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,50 @@ | ||
package io.newm.shared | ||
|
||
class NewmAppAnalyticsTracker : AppAnalyticsTracker { | ||
|
||
private var appAnalyticsTracker: AppAnalyticsTracker? = null | ||
|
||
fun setClientAnalyticsTracker(clientTracker: AppAnalyticsTracker) { | ||
appAnalyticsTracker = clientTracker | ||
} | ||
|
||
override fun trackEvent(eventName: String, properties: Map<String, Any?>?) { | ||
appAnalyticsTracker?.trackEvent(eventName, properties) | ||
} | ||
|
||
override fun trackScreenView(screenName: String) { | ||
appAnalyticsTracker?.trackScreenView(screenName) | ||
} | ||
|
||
override fun setUserId(userId: String) { | ||
appAnalyticsTracker?.setUserId(userId) | ||
} | ||
|
||
override fun setUserProperty(name: String, value: String) { | ||
appAnalyticsTracker?.setUserProperty(name, value) | ||
} | ||
|
||
override fun trackScroll(startPosition: Int, endPosition: Int, screenName: String) { | ||
appAnalyticsTracker?.trackScroll(startPosition, endPosition, screenName) | ||
} | ||
|
||
override fun trackButtonInteraction(buttonName: String, eventType: String) { | ||
appAnalyticsTracker?.trackButtonInteraction(buttonName, eventType) | ||
} | ||
|
||
override fun trackPlayButtonClick(songId: String, songName: String) { | ||
appAnalyticsTracker?.trackPlayButtonClick(songId, songName) | ||
} | ||
|
||
override fun trackAppLaunch() { | ||
appAnalyticsTracker?.trackAppLaunch() | ||
} | ||
|
||
override fun trackAppClose() { | ||
appAnalyticsTracker?.trackAppClose() | ||
} | ||
|
||
override fun trackUserScroll(percentage: Double) { | ||
appAnalyticsTracker?.trackUserScroll(percentage) | ||
} | ||
} |
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