From 5ee979447f891bb715780b0ffd85b267fd521963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Fri, 14 Dec 2018 00:20:54 +0100 Subject: [PATCH] Migrate to firebase (#196) --- .circleci/config.yml | 5 +- .travis.yml | 7 +-- app/build.gradle | 23 ++++---- app/src/debug/google-services.json | 42 +++++++++++++++ app/src/debug/google-services.json.gpg | Bin 0 -> 637 bytes app/src/main/AndroidManifest.xml | 4 +- .../java/io/github/wulkanowy/WulkanowyApp.kt | 4 +- .../io/github/wulkanowy/data/ApiHelper.kt | 2 +- .../data/repositories/remote/GradeRemote.kt | 2 +- .../java/io/github/wulkanowy/di/AppModule.kt | 6 +++ .../ui/modules/about/AboutPresenter.kt | 12 ++++- .../modules/attendance/AttendancePresenter.kt | 10 ++-- .../summary/AttendanceSummaryPresenter.kt | 7 +-- .../ui/modules/exam/ExamPresenter.kt | 10 ++-- .../ui/modules/grade/GradePresenter.kt | 7 +-- .../grade/details/GradeDetailsPresenter.kt | 7 +-- .../grade/summary/GradeSummaryPresenter.kt | 7 +-- .../ui/modules/homework/HomeworkPresenter.kt | 10 ++-- .../modules/login/form/LoginFormPresenter.kt | 14 ++--- .../login/options/LoginOptionsPresenter.kt | 10 ++-- .../ui/modules/main/MainPresenter.kt | 18 ++++--- .../preview/MessagePreviewPresenter.kt | 12 +++-- .../message/tab/MessageTabPresenter.kt | 7 +-- .../ui/modules/note/NotePresenter.kt | 7 +-- .../ui/modules/settings/SettingsPresenter.kt | 7 +-- .../ui/modules/splash/SplashPresenter.kt | 7 +-- .../modules/timetable/TimetablePresenter.kt | 10 ++-- .../timetable/TimetableWidgetProvider.kt | 11 +++- .../io/github/wulkanowy/utils/FabricUtils.kt | 49 ------------------ .../utils/FirebaseAnalyticsHelper.kt | 23 ++++++++ app/src/release/google-services.json | 42 +++++++++++++++ app/src/release/google-services.json.gpg | Bin 0 -> 636 bytes .../repositories/remote/StudentRemoteTest.kt | 2 +- .../login/form/LoginFormPresenterTest.kt | 7 ++- .../options/LoginOptionsPresenterTest.kt | 6 ++- .../ui/modules/main/MainPresenterTest.kt | 6 ++- build.gradle | 3 +- 37 files changed, 255 insertions(+), 151 deletions(-) create mode 100644 app/src/debug/google-services.json create mode 100644 app/src/debug/google-services.json.gpg delete mode 100644 app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt create mode 100644 app/src/main/java/io/github/wulkanowy/utils/FirebaseAnalyticsHelper.kt create mode 100644 app/src/release/google-services.json create mode 100644 app/src/release/google-services.json.gpg diff --git a/.circleci/config.yml b/.circleci/config.yml index 717d3bdf..0fed935d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -113,7 +113,7 @@ jobs: adb shell input keyevent 82 - run: name: Run instrumented tests - command: ./gradlew clean createDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex -PdisableCrashlytics + command: ./gradlew clean createDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex - run: name: Collect logs from emulator command: adb logcat -d > ./app/build/reports/logcat_emulator.txt @@ -153,11 +153,12 @@ jobs: - run: name: Decrypt keys command: | + gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg openssl aes-256-cbc -d -in ./app/key-encrypted.p12 -k $ENCRYPT_KEY >> ./app/key.p12 openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks - run: name: Publish release - command: ./gradlew publishRelease --no-daemon --stacktrace --console=plain -PdisablePreDex + command: ./gradlew publishRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex workflows: version: 2 diff --git a/.travis.yml b/.travis.yml index 493813dd..828aa43b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,17 +49,18 @@ script: - fossa --no-ansi || true - ./gradlew lint -x fabricGenerateResourcesRelease --stacktrace --daemon - ./gradlew test -x fabricGenerateResourcesRelease --stacktrace --daemon - - ./gradlew createDebugCoverageReport --stacktrace -PdisableCrashlytics --daemon + - ./gradlew createDebugCoverageReport --stacktrace --daemon - ./gradlew jacocoTestReport --stacktrace --daemon - if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" == "master" ]; then git fetch --unshallow; - ./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} -PdisableCrashlytics --stacktrace --daemon; + ./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon; fi - | if [ $TRAVIS_TAG ]; then + gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg; openssl aes-256-cbc -d -in ./app/key-encrypted.p12 -k $ENCRYPT_KEY >> ./app/key.p12; openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks; - ./gradlew publishRelease --stacktrace; + ./gradlew publishRelease -PenableCrashlytics --stacktrace; fi after_success: diff --git a/app/build.gradle b/app/build.gradle index 23fa9254..8a965c5e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,6 @@ apply plugin: 'com.github.triplet.play' apply from: 'jacoco.gradle' apply from: 'sonarqube.gradle' -def fabricApiKey = System.getenv("FABRIC_API_KEY") ?: "null" - android { compileSdkVersion 28 buildToolsVersion '28.0.3' @@ -31,7 +29,7 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true playAccountConfig = playAccountConfigs.defaultAccountConfig - manifestPlaceholders = [fabricApiKey: fabricApiKey] + manifestPlaceholders = [crashlytics_enabled: project.hasProperty("enableCrashlytics")] } signingConfigs { @@ -45,17 +43,17 @@ android { buildTypes { release { - buildConfigField "boolean", "FABRIC_ENABLED", "true" + buildConfigField "boolean", "CRASHLYTICS_ENABLED", "true" minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } debug { - buildConfigField "boolean", "FABRIC_ENABLED", fabricApiKey != "null" && !project.hasProperty("disableCrashlytics") ? "true" : "false" + buildConfigField "boolean", "CRASHLYTICS_ENABLED", project.hasProperty("enableCrashlytics") ? "true" : "false" applicationIdSuffix ".dev" versionNameSuffix "-dev" testCoverageEnabled = true - ext.enableCrashlytics = fabricApiKey != "null" && !project.hasProperty("disableCrashlytics") + ext.enableCrashlytics = project.hasProperty("enableCrashlytics") multiDexKeepProguard file('proguard-multidex-rules.pro') } } @@ -81,7 +79,7 @@ configurations.all { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - implementation('com.github.wulkanowy:api:6a73b0e') { exclude module: "threetenbp" } + implementation('com.github.wulkanowy:api:88e279e') { exclude module: "threetenbp" } implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.appcompat:appcompat:1.0.2" @@ -115,12 +113,9 @@ dependencies { implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" - implementation("com.crashlytics.sdk.android:crashlytics:2.9.7@aar") { - transitive = true - } - implementation("com.crashlytics.sdk.android:answers:1.4.5@aar") { - transitive = true - } + + implementation 'com.google.firebase:firebase-core:16.0.6' + implementation 'com.crashlytics.sdk.android:crashlytics:2.9.7' debugImplementation "com.amitshekhar.android:debug-db:1.0.4" @@ -135,3 +130,5 @@ dependencies { androidTestImplementation "org.mockito:mockito-android:2.23.4" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" } + +apply plugin: 'com.google.gms.google-services' diff --git a/app/src/debug/google-services.json b/app/src/debug/google-services.json new file mode 100644 index 00000000..e9303986 --- /dev/null +++ b/app/src/debug/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "", + "firebase_url": "", + "project_id": "", + "storage_bucket": "" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1091101852179:android:b558a25f65d088b1", + "android_client_info": { + "package_name": "io.github.wulkanowy.dev" + } + }, + "oauth_client": [ + { + "client_id": "", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} diff --git a/app/src/debug/google-services.json.gpg b/app/src/debug/google-services.json.gpg new file mode 100644 index 0000000000000000000000000000000000000000..736f7906d700cbb2aa7fb632975c80c4df84a82e GIT binary patch literal 637 zcmV-@0)qXF4Fm}T0;#}WYDh;T!T-|f0ewN>k_eoUDo!Q8_e(+-}RtcY;!+$<#P%tDsSs)99ZGmJGHy>intPiI+CQ%_1({K{J3?u-Hzw&Jf@~I znI|OBxnW=RhwvSUh+VX$F2YdM8`pK+wp^6~K`U2bnHB}y++UicJ&JFLOQ8ot|3|`$AIQ}! z6(3LEsGlv&ZXqX=xGrX;khP>BBWUh&E+1jrL^tg_EYq^-)+d&Dc>C?xJ_flP{``<~ zys-(^IjOEJJV*m=Swr}KM-AYZ4Z-CtI`9leMvI8(Jd+xy==s-`-e0q?gRpO}II0#|^`QLN9l+>}t8piQKhYX3W7Co#FEQMK4#- zn4f%3Qv3>e#i_dT{Ng|=pH*}_{ms2S4HWBE*7F|8>u;ZTIt$XAV00Wop- z^aAT^k?#gc%~dTW01kaep30v9NHfpf(_DgEW02bjv&9>^!?k$wVD? z{Ao&6Kto)hd{^eGUTWeCq*UIhVd8x*m;m2iR2qSs-GJr3lIZM9vFRH;rXeDE!VI|5mWaXo@)NrmBZ~ypnLi{ep^$ea$?dqM{dWKBN2P=I@YU+f1A({+61CR- X05Gn-%C>=!=u`42k-JHZi55YvN`*o? literal 0 HcmV?d00001 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dbbd5874..643fd292 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,7 +63,7 @@ + android:name="firebase_crashlytics_collection_enabled" + android:value="${crashlytics_enabled}" /> diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt index dcdd24af..628d6ce6 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt @@ -4,7 +4,6 @@ import android.content.Context import androidx.appcompat.app.AppCompatDelegate import androidx.multidex.MultiDex import com.crashlytics.android.Crashlytics -import com.crashlytics.android.answers.Answers import com.crashlytics.android.core.CrashlyticsCore import com.jakewharton.threetenabp.AndroidThreeTen import dagger.android.AndroidInjector @@ -45,8 +44,7 @@ class WulkanowyApp : DaggerApplication() { private fun initializeFabric() { Fabric.with(Fabric.Builder(this).kits( - Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!BuildConfig.FABRIC_ENABLED).build()).build(), - Answers() + Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!BuildConfig.CRASHLYTICS_ENABLED).build()).build() ).debuggable(BuildConfig.DEBUG).build()) Timber.plant(CrashlyticsTree()) } diff --git a/app/src/main/java/io/github/wulkanowy/data/ApiHelper.kt b/app/src/main/java/io/github/wulkanowy/data/ApiHelper.kt index 299c3b95..5b7b1072 100644 --- a/app/src/main/java/io/github/wulkanowy/data/ApiHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/ApiHelper.kt @@ -14,6 +14,7 @@ class ApiHelper @Inject constructor(private val api: Api) { symbol = student.symbol schoolSymbol = student.schoolSymbol studentId = student.studentId + useNewStudent = false host = URL(student.endpoint).run { host + ":$port".removeSuffix(":-1") } ssl = student.endpoint.startsWith("https") loginType = Api.LoginType.valueOf(student.loginType) @@ -24,4 +25,3 @@ class ApiHelper @Inject constructor(private val api: Api) { initApi(Student(email = email, password = password, symbol = symbol, endpoint = endpoint, loginType = "AUTO")) } } - diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt index 06e4d683..df3bf4d2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt @@ -25,7 +25,7 @@ class GradeRemote @Inject constructor(private val api: Api) { modifier = it.modifier, comment = it.comment, color = it.color, - gradeSymbol = it.symbol, + gradeSymbol = it.symbol ?: "", description = it.description, weight = it.weight, weightValue = it.weightValue, diff --git a/app/src/main/java/io/github/wulkanowy/di/AppModule.kt b/app/src/main/java/io/github/wulkanowy/di/AppModule.kt index 7ad855ae..fc2e9297 100644 --- a/app/src/main/java/io/github/wulkanowy/di/AppModule.kt +++ b/app/src/main/java/io/github/wulkanowy/di/AppModule.kt @@ -3,11 +3,13 @@ package io.github.wulkanowy.di import android.content.Context import com.firebase.jobdispatcher.FirebaseJobDispatcher import com.firebase.jobdispatcher.GooglePlayDriver +import com.google.firebase.analytics.FirebaseAnalytics import dagger.Module import dagger.Provides import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.WulkanowyApp +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import javax.inject.Singleton @@ -28,4 +30,8 @@ internal class AppModule { @Singleton @Provides fun provideJobDispatcher(context: Context) = FirebaseJobDispatcher(GooglePlayDriver(context)) + + @Singleton + @Provides + fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context)) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index d0ca64f9..7a1f665c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -6,23 +6,31 @@ import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2 import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL3 import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import timber.log.Timber import javax.inject.Inject -class AboutPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter(errorHandler) { +class AboutPresenter @Inject constructor( + errorHandler: ErrorHandler, + private val analytics: FirebaseAnalyticsHelper +) : BasePresenter(errorHandler) { fun onExtraSelect(type: Libs.SpecialButton?) { view?.run { when (type) { SPECIAL1 -> { Timber.i("Opening github page") + analytics.logEvent("open_page", mapOf("name" to "github")) openSourceWebView() } SPECIAL2 -> { Timber.i("Opening issues page") + analytics.logEvent("open_page", mapOf("name" to "issues")) openIssuesWebView() } - SPECIAL3 -> { } + SPECIAL3 -> { + //empty for now + } } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt index 74e585d4..4a03600e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.attendance +import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.repositories.AttendanceRepository import io.github.wulkanowy.data.repositories.PreferencesRepository @@ -7,9 +8,9 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousOrSameSchoolDay import io.github.wulkanowy.utils.previousSchoolDay @@ -26,7 +27,8 @@ class AttendancePresenter @Inject constructor( private val attendanceRepository: AttendanceRepository, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, - private val prefRepository: PreferencesRepository + private val prefRepository: PreferencesRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -42,13 +44,11 @@ class AttendancePresenter @Inject constructor( fun onPreviousDay() { loadData(currentDate.previousSchoolDay) reloadView() - logEvent("Attendance day changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString())) } fun onNextDay() { loadData(currentDate.nextSchoolDay) reloadView() - logEvent("Attendance day changed", mapOf("button" to "next", "date" to currentDate.toFormattedString())) } fun onSwipeRefresh() { @@ -105,7 +105,7 @@ class AttendancePresenter @Inject constructor( showEmpty(it.isEmpty()) showContent(it.isNotEmpty()) } - logEvent("Attendance load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString())) + analytics.logEvent("load_attendance", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt index 931d3263..2fcd88f2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt @@ -8,10 +8,10 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.SubjectRepostory import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.calculatePercentage import io.github.wulkanowy.utils.getFormattedName -import io.github.wulkanowy.utils.logEvent import java.lang.String.format import java.util.Locale.FRANCE import java.util.concurrent.TimeUnit.MILLISECONDS @@ -23,7 +23,8 @@ class AttendanceSummaryPresenter @Inject constructor( private val subjectRepository: SubjectRepostory, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, - private val schedulers: SchedulersProvider + private val schedulers: SchedulersProvider, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { private var subjects = emptyList() @@ -74,7 +75,7 @@ class AttendanceSummaryPresenter @Inject constructor( showContent(it.first.isNotEmpty()) updateDataSet(it.first, it.second) } - logEvent("Attendance load", mapOf("forceRefresh" to forceRefresh)) + analytics.logEvent("load_attendance_summary", mapOf("items" to it.first.size, "force_refresh" to forceRefresh, "item_id" to subjectId)) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt index fbf9712a..a9e8d241 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.exam +import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.data.repositories.ExamRepository @@ -7,10 +8,10 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.friday import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.toFormattedString @@ -25,7 +26,8 @@ class ExamPresenter @Inject constructor( private val schedulers: SchedulersProvider, private val examRepository: ExamRepository, private val studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository + private val semesterRepository: SemesterRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -41,13 +43,11 @@ class ExamPresenter @Inject constructor( fun onPreviousWeek() { loadData(currentDate.minusDays(7)) reloadView() - logEvent("Exam week changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString())) } fun onNextWeek() { loadData(currentDate.plusDays(7)) reloadView() - logEvent("Exam week changed", mapOf("button" to "next", "date" to currentDate.toFormattedString())) } fun onSwipeRefresh() { @@ -92,7 +92,7 @@ class ExamPresenter @Inject constructor( showEmpty(it.isEmpty()) showContent(it.isNotEmpty()) } - logEvent("Exam load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString())) + analytics.logEvent("load_exam", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt index 4d5b56db..4920a8d6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt @@ -5,8 +5,8 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logEvent import io.reactivex.Completable import java.util.concurrent.TimeUnit.MILLISECONDS import javax.inject.Inject @@ -15,7 +15,8 @@ class GradePresenter @Inject constructor( private val errorHandler: MainErrorHandler, private val schedulers: SchedulersProvider, private val studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository + private val semesterRepository: SemesterRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { var selectedIndex = 0 @@ -52,7 +53,7 @@ class GradePresenter @Inject constructor( notifyChildrenSemesterChange() loadChild(it.currentPageIndex) } - logEvent("Semester changed", mapOf("number" to index + 1)) + analytics.logEvent("changed_semester", mapOf("number" to index + 1)) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt index 654550e4..8034deea 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt @@ -8,10 +8,10 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.calcAverage import io.github.wulkanowy.utils.changeModifier -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.valueColor import timber.log.Timber import javax.inject.Inject @@ -22,7 +22,8 @@ class GradeDetailsPresenter @Inject constructor( private val gradeRepository: GradeRepository, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { private var currentSemesterId = 0 @@ -113,7 +114,7 @@ class GradeDetailsPresenter @Inject constructor( showContent(it.isNotEmpty()) updateData(it) } - logEvent("Grade details load", mapOf("items" to it.size, "forceRefresh" to forceRefresh)) + analytics.logEvent("load_grade_details", mapOf("items" to it.size, "force_refresh" to forceRefresh)) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt index 2715aac4..3ae1cd24 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt @@ -8,10 +8,10 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.calcAverage import io.github.wulkanowy.utils.changeModifier -import io.github.wulkanowy.utils.logEvent import java.lang.String.format import java.util.Locale.FRANCE import javax.inject.Inject @@ -23,7 +23,8 @@ class GradeSummaryPresenter @Inject constructor( private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, private val preferencesRepository: PreferencesRepository, - private val schedulers: SchedulersProvider + private val schedulers: SchedulersProvider, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { override fun onAttachView(view: GradeSummaryView) { @@ -68,7 +69,7 @@ class GradeSummaryPresenter @Inject constructor( showContent(it.first.isNotEmpty()) updateData(it.first, it.second) } - logEvent("Grade summary load", mapOf("items" to it.first.size, "forceRefresh" to forceRefresh)) + analytics.logEvent("load_grade_summary", mapOf("items" to it.first.size, "force_refresh" to forceRefresh)) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt index 2687b2d8..9e621e05 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt @@ -1,14 +1,15 @@ package io.github.wulkanowy.ui.modules.homework +import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.repositories.HomeworkRepository import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousSchoolDay @@ -22,7 +23,8 @@ class HomeworkPresenter @Inject constructor( private val schedulers: SchedulersProvider, private val homeworkRepository: HomeworkRepository, private val studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository + private val semesterRepository: SemesterRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -38,13 +40,11 @@ class HomeworkPresenter @Inject constructor( fun onPreviousDay() { loadData(currentDate.previousSchoolDay) reloadView() - logEvent("Homework day changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString())) } fun onNextDay() { loadData(currentDate.nextSchoolDay) reloadView() - logEvent("Homework day changed", mapOf("button" to "next", "date" to currentDate.toFormattedString())) } fun onSwipeRefresh() { @@ -78,7 +78,7 @@ class HomeworkPresenter @Inject constructor( showEmpty(it.isEmpty()) showContent(it.isNotEmpty()) } - logEvent("Homework load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString())) + analytics.logEvent("load_homework", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))) }) { view?.run { showEmpty(isViewEmpty()) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index 5b6d4bd2..58ce34a7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -1,18 +1,21 @@ package io.github.wulkanowy.ui.modules.login.form +import com.google.firebase.analytics.FirebaseAnalytics.Event.SIGN_UP +import com.google.firebase.analytics.FirebaseAnalytics.Param.GROUP_ID +import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.login.LoginErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logEvent -import io.github.wulkanowy.utils.logRegister import timber.log.Timber import javax.inject.Inject class LoginFormPresenter @Inject constructor( private val schedulers: SchedulersProvider, private val errorHandler: LoginErrorHandler, - private val studentRepository: StudentRepository + private val studentRepository: StudentRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { private var wasEmpty = false @@ -57,15 +60,14 @@ class LoginFormPresenter @Inject constructor( } else if (it.isEmpty() && wasEmpty) { showSymbolInput() setErrorSymbolIncorrect() - logRegister("No student found", false, if (symbol.isEmpty()) "nil" else symbol, endpoint) + analytics.logEvent(SIGN_UP, mapOf(SUCCESS to false, "students" to it.size, "endpoint" to endpoint, GROUP_ID to symbol.ifEmpty { "nil" })) } else { switchOptionsView() - logEvent("Found students", mapOf("students" to it.size, "symbol" to it.joinToString { student -> student.symbol }, "endpoint" to endpoint)) } } }, { + analytics.logEvent(SIGN_UP, mapOf(SUCCESS to true, "endpoint" to endpoint, GROUP_ID to symbol.ifEmpty { "nil" })) errorHandler.dispatch(it) - logRegister(it.localizedMessage, false, if (symbol.isEmpty()) "nil" else symbol, endpoint) })) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt index 9187a583..af9ae692 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt @@ -1,13 +1,16 @@ package io.github.wulkanowy.ui.modules.login.options +import com.google.firebase.analytics.FirebaseAnalytics.Event.SIGN_UP +import com.google.firebase.analytics.FirebaseAnalytics.Param.GROUP_ID +import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.login.LoginErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logRegister import io.reactivex.Single import javax.inject.Inject @@ -15,7 +18,8 @@ class LoginOptionsPresenter @Inject constructor( private val errorHandler: LoginErrorHandler, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, - private val schedulers: SchedulersProvider + private val schedulers: SchedulersProvider, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { override fun onAttachView(view: LoginOptionsView) { @@ -56,7 +60,7 @@ class LoginOptionsPresenter @Inject constructor( } } .subscribe({ - logRegister("Success", true, student.symbol, student.endpoint) + analytics.logEvent(SIGN_UP, mapOf(SUCCESS to true, "students" to 1, "endpoint" to student.endpoint, GROUP_ID to student.symbol)) view?.openMainView() }, { errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index c62afced..34e762b2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt @@ -1,11 +1,13 @@ package io.github.wulkanowy.ui.modules.main +import com.google.firebase.analytics.FirebaseAnalytics.Event.APP_OPEN +import com.google.firebase.analytics.FirebaseAnalytics.Param.DESTINATION import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.services.job.ServiceHelper import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logLogin import io.reactivex.Completable import javax.inject.Inject @@ -14,7 +16,8 @@ class MainPresenter @Inject constructor( private val studentRepository: StudentRepository, private val prefRepository: PreferencesRepository, private val schedulers: SchedulersProvider, - private val serviceHelper: ServiceHelper + private val serviceHelper: ServiceHelper, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { fun onAttachView(view: MainView, initMenuIndex: Int) { @@ -27,11 +30,12 @@ class MainPresenter @Inject constructor( } serviceHelper.startFullSyncService() - when (initMenuIndex) { - 1 -> logLogin("Grades") - 3 -> logLogin("Timetable") - 4 -> logLogin("More") - } + analytics.logEvent(APP_OPEN, mapOf(DESTINATION to when (initMenuIndex) { + 1 -> "Grades" + 3 -> "Timetable" + 4 -> "More" + else -> "User action" + })) } fun onViewStart() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt index 298e299b..3d8f81d8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt @@ -1,11 +1,12 @@ package io.github.wulkanowy.ui.modules.message.preview +import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.repositories.MessagesRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.toFormattedString import javax.inject.Inject @@ -13,7 +14,8 @@ class MessagePreviewPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val messagesRepository: MessagesRepository, - private val studentRepository: StudentRepository + private val studentRepository: StudentRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { var messageId: Int = 0 @@ -32,9 +34,9 @@ class MessagePreviewPresenter @Inject constructor( .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) .doFinally { view?.showProgress(false) } - .subscribe({ messages -> + .subscribe({ message -> view?.run { - messages.let { + message.let { setSubject(if (it.subject.isNotBlank()) it.subject else noSubjectString) setDate(it.date?.toFormattedString("yyyy-MM-dd HH:mm:ss")) setContent(it.content) @@ -43,7 +45,7 @@ class MessagePreviewPresenter @Inject constructor( else setSender(it.sender) } } - logEvent("Message load", mapOf("length" to messages.content?.length)) + analytics.logEvent("load_attendance", mapOf(START_DATE to message.date?.toFormattedString("yyyy.MM.dd"), "lenght" to message.content?.length)) }) { view?.showMessageError() errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt index 93ee033a..417900f0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt @@ -7,8 +7,8 @@ import io.github.wulkanowy.data.repositories.MessagesRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.message.MessageItem +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logEvent import timber.log.Timber import javax.inject.Inject @@ -16,7 +16,8 @@ class MessageTabPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val messagesRepository: MessagesRepository, - private val studentRepository: StudentRepository + private val studentRepository: StudentRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { lateinit var folder: MessagesRepository.MessageFolder @@ -52,7 +53,7 @@ class MessageTabPresenter @Inject constructor( showContent(it.isNotEmpty()) updateData(it) } - logEvent("Message tab load", mapOf("items" to it.size, "forceRefresh" to forceRefresh)) + analytics.logEvent("load_messages", mapOf("items" to it.size, "folder" to folder.name)) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt index 07ddc6ae..6a283c4f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt @@ -7,8 +7,8 @@ import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider -import io.github.wulkanowy.utils.logEvent import timber.log.Timber import javax.inject.Inject @@ -17,7 +17,8 @@ class NotePresenter @Inject constructor( private val schedulers: SchedulersProvider, private val studentRepository: StudentRepository, private val noteRepository: NoteRepository, - private val semesterRepository: SemesterRepository + private val semesterRepository: SemesterRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { override fun onAttachView(view: NoteView) { @@ -49,7 +50,7 @@ class NotePresenter @Inject constructor( showEmpty(it.isEmpty()) showContent(it.isNotEmpty()) } - logEvent("Note load", mapOf("items" to it.size, "forceRefresh" to forceRefresh)) + analytics.logEvent("load_note", mapOf("items" to it.size, "force_refresh" to forceRefresh)) }, { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt index 2b01f9bf..647a0b35 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt @@ -4,15 +4,16 @@ import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.services.job.ServiceHelper import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.logEvent import org.threeten.bp.LocalDate.now import javax.inject.Inject class SettingsPresenter @Inject constructor( errorHandler: ErrorHandler, private val preferencesRepository: PreferencesRepository, - private val serviceHelper: ServiceHelper + private val serviceHelper: ServiceHelper, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { override fun onAttachView(view: SettingsView) { @@ -38,6 +39,6 @@ class SettingsPresenter @Inject constructor( } } - logEvent("Setting changed", mapOf("name" to key)) + analytics.logEvent("setting_changed", mapOf("name" to key)) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt index 949cb8c8..81823bf4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt @@ -3,7 +3,6 @@ package io.github.wulkanowy.ui.modules.splash import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.utils.logLogin import javax.inject.Inject class SplashPresenter @Inject constructor( @@ -14,10 +13,8 @@ class SplashPresenter @Inject constructor( override fun onAttachView(view: SplashView) { super.onAttachView(view) view.run { - if (studentRepository.isStudentSaved) { - logLogin("Open app") - openMainView() - } else openLoginView() + if (studentRepository.isStudentSaved) openMainView() + else openLoginView() } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index 4c5630dd..2d56ed49 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -1,14 +1,15 @@ package io.github.wulkanowy.ui.modules.timetable +import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.main.MainErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.logEvent import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousSchoolDay @@ -24,7 +25,8 @@ class TimetablePresenter @Inject constructor( private val schedulers: SchedulersProvider, private val timetableRepository: TimetableRepository, private val studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository + private val semesterRepository: SemesterRepository, + private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -40,13 +42,11 @@ class TimetablePresenter @Inject constructor( fun onPreviousDay() { loadData(currentDate.previousSchoolDay) reloadView() - logEvent("Timetable day changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString())) } fun onNextDay() { loadData(currentDate.nextSchoolDay) reloadView() - logEvent("Timetable day changed", mapOf("button" to "next", "date" to currentDate.toFormattedString())) } fun onSwipeRefresh() { @@ -90,7 +90,7 @@ class TimetablePresenter @Inject constructor( showEmpty(it.isEmpty()) showContent(it.isNotEmpty()) } - logEvent("Timetable load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString())) + analytics.logEvent("load_attendance", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))) }) { view?.run { showEmpty(isViewEmpty) } errorHandler.dispatch(it) diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt index 8439aed4..a8ead8fb 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt @@ -15,7 +15,7 @@ import io.github.wulkanowy.data.db.SharedPrefHelper import io.github.wulkanowy.services.widgets.TimetableWidgetService import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX -import io.github.wulkanowy.utils.logEvent +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousSchoolDay @@ -29,6 +29,9 @@ class TimetableWidgetProvider : AppWidgetProvider() { @Inject lateinit var sharedPref: SharedPrefHelper + @Inject + lateinit var analytics: FirebaseAnalyticsHelper + companion object { const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget" @@ -91,7 +94,11 @@ class TimetableWidgetProvider : AppWidgetProvider() { } BUTTON_RESET -> sharedPref.putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true) } - button?.also { btn -> if (btn.isNotBlank()) logEvent("Widget day changed", mapOf("button" to button)) } + button?.also { btn -> + if (btn.isNotBlank()) { + analytics.logEvent("changed_timetable_widget_day", mapOf("button" to button)) + } + } } } super.onReceive(context, intent) diff --git a/app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt deleted file mode 100644 index d8fc3a1d..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt +++ /dev/null @@ -1,49 +0,0 @@ -package io.github.wulkanowy.utils - -import com.crashlytics.android.answers.Answers -import com.crashlytics.android.answers.CustomEvent -import com.crashlytics.android.answers.LoginEvent -import com.crashlytics.android.answers.SignUpEvent -import timber.log.Timber -import kotlin.math.min - -fun logLogin(method: String) { - try { - Answers.getInstance().logLogin(LoginEvent().putMethod(method)) - } catch (e: Throwable) { - Timber.d(e) - } -} - -fun logRegister(message: String, result: Boolean, symbol: String, endpoint: String) { - try { - Answers.getInstance().logSignUp(SignUpEvent() - .putMethod("Login activity") - .putSuccess(result) - .putCustomAttribute("symbol", symbol) - .putCustomAttribute("message", message.substring(0, min(message.length, 100))) - .putCustomAttribute("endpoint", endpoint) - ) - } catch (e: Throwable) { - Timber.d(e) - } -} - -fun logEvent(name: String, params: Map) { - try { - Answers.getInstance().logCustom(CustomEvent(name) - .apply { - params.forEach { - when { - it.value is String -> putCustomAttribute(it.key, it.value as String) - it.value is Number -> putCustomAttribute(it.key, it.value as Number) - it.value is Boolean -> putCustomAttribute(it.key, if ((it.value as Boolean)) "true" else "false") - else -> Timber.w("logEvent() unknown value type: ${it.value}") - } - } - } - ) - } catch (e: Throwable) { - Timber.d(e) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/FirebaseAnalyticsHelper.kt b/app/src/main/java/io/github/wulkanowy/utils/FirebaseAnalyticsHelper.kt new file mode 100644 index 00000000..53f9197f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/FirebaseAnalyticsHelper.kt @@ -0,0 +1,23 @@ +package io.github.wulkanowy.utils + +import android.os.Bundle +import com.google.firebase.analytics.FirebaseAnalytics +import javax.inject.Singleton + +@Singleton +class FirebaseAnalyticsHelper(private val analytics: FirebaseAnalytics) { + + fun logEvent(name: String, params: Map) { + Bundle().apply { + params.forEach { + if (it.value == null) return@forEach + when (it.value) { + is String, is String? -> putString(it.key, it.value as String) + is Int, is Int? -> putInt(it.key, it.value as Int) + is Boolean, is Boolean? -> putBoolean(it.key, it.value as Boolean) + } + } + analytics.logEvent(name, this) + } + } +} diff --git a/app/src/release/google-services.json b/app/src/release/google-services.json new file mode 100644 index 00000000..ebd157e1 --- /dev/null +++ b/app/src/release/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "", + "firebase_url": "", + "project_id": "", + "storage_bucket": "" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1091101852179:android:b558a25f65d088b1", + "android_client_info": { + "package_name": "io.github.wulkanowy" + } + }, + "oauth_client": [ + { + "client_id": "", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} diff --git a/app/src/release/google-services.json.gpg b/app/src/release/google-services.json.gpg new file mode 100644 index 0000000000000000000000000000000000000000..58534ca5b2e1d423f85f8bb6f7d4a29a21c21cd6 GIT binary patch literal 636 zcmV-?0)zdG4Fm}T0_T0n^-V(l!vE6g0r(W(3$8FX_XVtuX%FAjIU^e3qC=e9`iL_f zCGvKswiRpbL(ro)f`3adcJF%XE&yrLY?P~KgM2(v9wrJ{?u&WmWJB3}M<`)qmh5pE z7q(({;ADC!ZT7JokrimHUvn#G*e(-v_v%)4Gg87d?;FJ;+qth8xT9bB*IK)PQDD^F zK{fK4t2Nlcw$~v`v`Yn4w;*gdXXFh&2W_4+Gb1GaF(9MkMi$ZpC*DXsO|SBY4DeAn zPjx6Ywp>L+MMPujW(!;(>0a7)g+VoPU;~ z-tgYZB8v%?$xZ#xm%)vpPrNyD7$?*CJ&+a-99A7;!->uc{072nN&wpHZmTZ+GCxe4XqNLV8=N`IRU?{)oGo}(I|G^!0L448F~zyJ`dGv zf@U2enSyLwnVf*yp5w0Uy;c=22{6)=Xj|FgO}AjKaZ z-9O@mLCV`|Z~B_iGy+0YYJWG=lG8Nd;#wuS2w&W8KTPGq=cN^hfS-O>Po?+tP?bb2 z5%-~J1!>FnOn6d%iY|Qeo?Dah=`sSIt=vF}F^BHORgE7ML*cfCYyl%@A(op@j=_8J W;=L}bTZ)p>R*-3nS4)7oP&I3cR4;`9 literal 0 HcmV?d00001 diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt index 1e615c9c..09082ec8 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt @@ -22,7 +22,7 @@ class StudentRemoteTest { @Test fun testRemoteAll() { - doReturn(Single.just(listOf(Pupil("", "", 1, "test", "", "", Api.LoginType.AUTO)))) + doReturn(Single.just(listOf(Pupil("", "", 1, "test", "", "", "", Api.LoginType.AUTO)))) .`when`(mockApi).getPupils() val students = StudentRemote(mockApi).getStudents("", "", "").blockingGet() diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt index 279ad9c9..05d2e399 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt @@ -4,6 +4,7 @@ import io.github.wulkanowy.TestSchedulersProvider import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.modules.login.LoginErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.reactivex.Single import org.junit.Before import org.junit.Test @@ -27,13 +28,16 @@ class LoginFormPresenterTest { @Mock lateinit var errorHandler: LoginErrorHandler + @Mock + lateinit var analytics: FirebaseAnalyticsHelper + private lateinit var presenter: LoginFormPresenter @Before fun initPresenter() { MockitoAnnotations.initMocks(this) clearInvocations(repository, loginFormView) - presenter = LoginFormPresenter(TestSchedulersProvider(), errorHandler, repository) + presenter = LoginFormPresenter(TestSchedulersProvider(), errorHandler, repository, analytics) presenter.onAttachView(loginFormView) } @@ -125,7 +129,6 @@ class LoginFormPresenterTest { verify(loginFormView, times(2)).showContent(true) verify(loginFormView, times(2)).showSymbolInput() verify(loginFormView).setErrorSymbolIncorrect() - } @Test diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt index cc4184db..939d017f 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt @@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.modules.login.LoginErrorHandler +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.reactivex.Completable import io.reactivex.Single import org.junit.Before @@ -30,6 +31,9 @@ class LoginOptionsPresenterTest { @Mock lateinit var semesterRepository: SemesterRepository + @Mock + lateinit var analytics: FirebaseAnalyticsHelper + private lateinit var presenter: LoginOptionsPresenter private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO") } @@ -41,7 +45,7 @@ class LoginOptionsPresenterTest { MockitoAnnotations.initMocks(this) clearInvocations(studentRepository, loginOptionsView) clearInvocations(semesterRepository, loginOptionsView) - presenter = LoginOptionsPresenter(errorHandler, studentRepository, semesterRepository, TestSchedulersProvider()) + presenter = LoginOptionsPresenter(errorHandler, studentRepository, semesterRepository, TestSchedulersProvider(), analytics) presenter.onAttachView(loginOptionsView) } diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt index 1c8a1833..15d80ee4 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt @@ -4,6 +4,7 @@ import io.github.wulkanowy.TestSchedulersProvider import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.services.job.ServiceHelper +import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import org.junit.Before import org.junit.Test import org.mockito.Mock @@ -28,6 +29,9 @@ class MainPresenterTest { @Mock lateinit var mainView: MainView + @Mock + lateinit var analytics: FirebaseAnalyticsHelper + private lateinit var presenter: MainPresenter @Before @@ -35,7 +39,7 @@ class MainPresenterTest { MockitoAnnotations.initMocks(this) clearInvocations(mainView) - presenter = MainPresenter(errorHandler, studentRepository, prefRepository, TestSchedulersProvider(), serviceHelper) + presenter = MainPresenter(errorHandler, studentRepository, prefRepository, TestSchedulersProvider(), serviceHelper, analytics) presenter.onAttachView(mainView, -1) } diff --git a/build.gradle b/build.gradle index 95b800a1..89f697aa 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,8 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.android.tools.build:gradle:3.2.1' - classpath "io.fabric.tools:gradle:1.26.0" + classpath 'com.google.gms:google-services:4.2.0' + classpath "io.fabric.tools:gradle:1.26.1" classpath "com.github.triplet.gradle:play-publisher:1.2.2" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2" classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'