Skip to content

Commit

Permalink
Created new management for notifications and deferred FA instantiation
Browse files Browse the repository at this point in the history
By using inheritance, the "NotificationsWorker" class was removed in place of four new classes:
- AbstractNotificationsWorker, which contains the entire logic for publishing notifications.
- BreakfastWorker, LunchWorker, DinnerWorker which contains the data in order to allow parent class to work.
In addition, I detected that sometimes FirebaseInstantiation takes too much time so then the notification is never published. That's why I created with Kotlin coroutines a method for deferring the FA instantiation
  • Loading branch information
Javinator9889 committed Apr 22, 2020
1 parent 3651620 commit 4deb319
Show file tree
Hide file tree
Showing 24 changed files with 398 additions and 237 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -17,3 +17,4 @@ secrets.properties
api-5245190277294621651-718463-f914fb7573c6.json
*.jks
google-services.json
services.xml
2 changes: 1 addition & 1 deletion ads/build.gradle
Expand Up @@ -33,7 +33,7 @@ dependencies {
// https://developer.android.com/kotlin/ktx#play-core
implementation 'com.google.android.play:core-ktx:1.7.0'
// https://firebase.google.com/docs/admob/android/quick-start#import_the_mobile_ads_sdk
implementation 'com.google.firebase:firebase-ads:19.0.1'
implementation 'com.google.firebase:firebase-ads:19.1.0'
// https://developer.android.com/studio/build/multidex
implementation 'androidx.multidex:multidex:2.0.1'
// https://github.com/JakeWharton/timber
Expand Down
11 changes: 5 additions & 6 deletions app/build.gradle
Expand Up @@ -3,9 +3,8 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.google.firebase.crashlytics'


def secretsPropertiesFile = rootProject.file("secrets.properties")
Expand Down Expand Up @@ -43,8 +42,8 @@ android {
applicationId "com.javinator9889.handwashingreminder"
minSdkVersion 17
targetSdkVersion 29
versionCode 103
versionName "1.1.0-${gitCommitHash}"
versionCode 105
versionName "1.1.1-${gitCommitHash}"
multiDexEnabled true
resConfigs "en", "es"

Expand Down Expand Up @@ -143,7 +142,6 @@ dependencies {
// https://kotlinlang.org/docs/reference/reflection.html
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
// https://firebase.google.com/docs/android/setup#add-sdks
implementation 'com.google.firebase:firebase-core:17.3.0'
implementation 'com.google.firebase:firebase-common-ktx:19.3.0'
implementation 'com.google.firebase:firebase-analytics:17.3.0'
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta04'
Expand All @@ -152,6 +150,7 @@ dependencies {
implementation "com.airbnb.android:lottie:3.4.0"
// https://firebase.google.com/docs/remote-config/use-config-android
implementation 'com.google.firebase:firebase-config:19.1.3'
implementation 'com.google.firebase:firebase-config-ktx:19.1.3'
// https://developer.android.com/jetpack/androidx/releases/work#declaring_dependencies
implementation 'androidx.work:work-runtime-ktx:2.3.4'
// https://mvnrepository.com/artifact/androidx.emoji/emoji/1.0.0
Expand All @@ -172,7 +171,7 @@ dependencies {
// https://developer.android.com/jetpack/androidx/releases/lifecycle#declaring_dependencies
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
// https://developer.android.com/reference/kotlin/androidx/preference/package-summary
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
// https://github.com/bumptech/glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Expand Up @@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.INTERNET" />
Expand Down Expand Up @@ -75,6 +76,10 @@
</intent-filter>
</receiver>
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
tools:node="remove" />
</application>

</manifest>
Expand Up @@ -32,9 +32,10 @@ import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.play.core.splitcompat.SplitCompat
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.FirebasePerformance
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.javinator9889.handwashingreminder.R
import com.javinator9889.handwashingreminder.application.HandwashingApplication
import com.javinator9889.handwashingreminder.emoji.EmojiLoader
Expand All @@ -55,6 +56,7 @@ import timber.log.Timber
import java.security.Security
import java.util.*
import kotlin.collections.ArrayList
import com.javinator9889.handwashingreminder.utils.Firebase as FirebaseConf

internal const val FAST_START_KEY = "intent:fast_start"
internal const val PENDING_INTENT_CODE = 201
Expand Down Expand Up @@ -95,7 +97,8 @@ class LauncherActivity : AppCompatActivity() {
}

private suspend fun displayWelcomeScreen() {
val isThereAnySpecialEvent = with(FirebaseRemoteConfig.getInstance()) {
app.firebaseInitDeferred.await()
val isThereAnySpecialEvent = with(Firebase.remoteConfig) {
getBoolean(SPECIAL_EVENT) && !launchFromNotification
}
var sleepDuration = 0L
Expand Down Expand Up @@ -236,7 +239,9 @@ class LauncherActivity : AppCompatActivity() {
it.putExtra(DynamicFeatureProgress.PACKAGE_NAME, packageName)
}

private fun initVariables() {
private suspend fun initVariables() {
app.firebaseInitDeferred.await()
Timber.d("Firebase initialized correctly")
Timber.d("Initializing Iconics")
Iconics.init(this)
Timber.d("Setting-up security providers")
Expand Down Expand Up @@ -265,7 +270,7 @@ class LauncherActivity : AppCompatActivity() {

private fun setupFirebaseProperties() {
val firebaseAnalytics = FirebaseAnalytics.getInstance(this)
val firebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
val firebaseRemoteConfig = Firebase.remoteConfig
val firebasePerformance = FirebasePerformance.getInstance()
val config = with(FirebaseRemoteConfigSettings.Builder()) {
minimumFetchIntervalInSeconds = 10
Expand All @@ -279,14 +284,14 @@ class LauncherActivity : AppCompatActivity() {
when (Locale.getDefault().language) {
Locale(LanguagesSupport.Language.SPANISH).language -> {
firebaseAnalytics.setUserProperty(
Firebase.Properties.LANGUAGE,
FirebaseConf.Properties.LANGUAGE,
LanguagesSupport.Language.SPANISH
)
R.xml.remote_config_defaults_es
}
else -> {
firebaseAnalytics.setUserProperty(
Firebase.Properties.LANGUAGE,
FirebaseConf.Properties.LANGUAGE,
LanguagesSupport.Language.ENGLISH
)
R.xml.remote_config_defaults
Expand Down
Expand Up @@ -29,8 +29,9 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.metrics.AddTrace
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.javinator9889.handwashingreminder.R
import com.javinator9889.handwashingreminder.activities.support.ActionBarBase
import com.javinator9889.handwashingreminder.activities.views.fragments.diseases.DiseasesFragment
Expand Down Expand Up @@ -61,7 +62,7 @@ class MainActivity : ActionBarBase(),
with(FirebaseAnalytics.getInstance(this)) {
setCurrentScreen(this@MainActivity, "Main view", null)
}
with(FirebaseRemoteConfig.getInstance()) {
with(Firebase.remoteConfig) {
fetchAndActivate()
}
delegateMenuIcons(menu)
Expand Down
Expand Up @@ -21,7 +21,8 @@ package com.javinator9889.handwashingreminder.activities.views.fragments.news
import android.os.Bundle
import android.view.View
import androidx.annotation.LayoutRes
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.javinator9889.handwashingreminder.R
import com.javinator9889.handwashingreminder.activities.base.BaseFragmentView
import com.javinator9889.handwashingreminder.utils.RemoteConfig
Expand All @@ -40,7 +41,7 @@ class NewsFragment : BaseFragmentView() {
ARG_UNDER_CONSTRUCTION_TEXT
)
} else {
with(FirebaseRemoteConfig.getInstance()) {
with(Firebase.remoteConfig) {
underConstructionText.text =
getString(RemoteConfig.WORK_IN_PROGRESS)
}
Expand Down
Expand Up @@ -45,6 +45,8 @@ class ActivityCheckbox : CheckBoxPreference {
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)

private var firstCheck = true

init {
var isViewDisabled = false
with(GoogleApiAvailability.getInstance()) {
Expand Down Expand Up @@ -83,6 +85,10 @@ class ActivityCheckbox : CheckBoxPreference {

override fun setChecked(checked: Boolean) {
super.setChecked(checked)
if (firstCheck) {
firstCheck = false
return
}
with(HandwashingApplication.getInstance()) {
if (checked) {
activityHandler.startTrackingActivity()
Expand Down
Expand Up @@ -29,6 +29,7 @@ import com.mikepenz.iconics.utils.sizeDp
import java.util.*

class ActivityMultiSelectList : MultiSelectListPreference {
private var isFirstCall = true
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
Expand All @@ -48,7 +49,10 @@ class ActivityMultiSelectList : MultiSelectListPreference {
override fun notifyChanged() {
super.notifyChanged()
loadSummary()
reloadActivityHandler()
if (!isFirstCall)
reloadActivityHandler()
else
isFirstCall = false
}

private fun loadSummary() {
Expand Down
Expand Up @@ -27,7 +27,8 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import com.beust.klaxon.Klaxon
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.javinator9889.handwashingreminder.collections.DiseasesInformation
import com.javinator9889.handwashingreminder.collections.DiseasesList
import com.javinator9889.handwashingreminder.collections.DiseasesListWrapper
Expand Down Expand Up @@ -55,7 +56,7 @@ class DiseaseInformationViewModel(
state.get<List<DiseasesInformation>>(PARSED_JSON_KEY)!!
)
val diseasesString =
with(FirebaseRemoteConfig.getInstance()) {
with(Firebase.remoteConfig) {
getString(DISEASES_JSON)
}
Klaxon().parse<DiseasesList>(diseasesString)
Expand Down
Expand Up @@ -42,7 +42,6 @@ import java.io.FileInputStream
import java.io.InputStream
import java.math.BigInteger
import java.security.MessageDigest
import javax.inject.Inject

private const val LIVEDATA_KEY = "videomodel:livedata"

Expand Down Expand Up @@ -128,7 +127,7 @@ class VideoModel(
}
}

class VideoModelFactory @Inject constructor(private val position: Int) :
class VideoModelFactory constructor(private val position: Int) :
ViewModelAssistedFactory<VideoModel> {
override fun create(handle: SavedStateHandle) = VideoModel(handle, position)
}
Expand Up @@ -27,7 +27,6 @@ import androidx.lifecycle.liveData
import com.javinator9889.handwashingreminder.R
import com.javinator9889.handwashingreminder.application.HandwashingApplication
import com.javinator9889.handwashingreminder.emoji.EmojiLoader
import javax.inject.Inject

internal data class Measurements(var width: Int, var height: Int)

Expand Down Expand Up @@ -102,7 +101,7 @@ class WashingHandsModel(
}
}

class WashingHandsModelFactory @Inject constructor(
class WashingHandsModelFactory constructor(
private val position: Int
) : ViewModelAssistedFactory<WashingHandsModel> {
override fun create(handle: SavedStateHandle) =
Expand Down
Expand Up @@ -20,9 +20,12 @@ package com.javinator9889.handwashingreminder.application

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.multidex.MultiDex
import androidx.preference.PreferenceManager
import com.google.android.play.core.splitcompat.SplitCompat
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.javinator9889.handwashingreminder.gms.activity.ActivityHandler
import com.javinator9889.handwashingreminder.gms.ads.AdLoader
Expand All @@ -31,6 +34,7 @@ import com.javinator9889.handwashingreminder.utils.LogReportTree
import com.javinator9889.handwashingreminder.utils.isDebuggable
import javinator9889.localemanager.application.BaseApplication
import javinator9889.localemanager.utils.languagesupport.LanguagesSupport.Language
import kotlinx.coroutines.*
import timber.log.Timber


Expand All @@ -39,6 +43,7 @@ class HandwashingApplication : BaseApplication() {
lateinit var billingService: BillingService
lateinit var activityHandler: ActivityHandler
lateinit var sharedPreferences: SharedPreferences
lateinit var firebaseInitDeferred: Deferred<Unit>

companion object {
private lateinit var instance: HandwashingApplication
Expand All @@ -61,17 +66,39 @@ class HandwashingApplication : BaseApplication() {
super.onCreate()
instance = this
sharedPreferences = getCustomSharedPreferences(this)

if (isDebuggable()) {
activityHandler = ActivityHandler(this)
/*if (isDebuggable()) {
Timber.plant(Timber.DebugTree())
Timber.d("Application is in DEBUG mode")
with(FirebaseCrashlytics.getInstance()) {
setCrashlyticsCollectionEnabled(false)
}
} else {
Timber.plant(LogReportTree())
}*/
firebaseInitDeferred = initFirebaseAppAsync()
Log.d("Application", "Deferred Firebase Instantiating")
}

private fun initFirebaseAppAsync(): Deferred<Unit> {
return GlobalScope.async {
withContext(Dispatchers.IO) {
FirebaseApp.initializeApp(
this@HandwashingApplication,
FirebaseOptions
.fromResource(this@HandwashingApplication)!!
)
if (isDebuggable()) {
Timber.plant(Timber.DebugTree())
Timber.d("Application is in DEBUG mode")
with(FirebaseCrashlytics.getInstance()) {
setCrashlyticsCollectionEnabled(false)
}
} else {
Timber.plant(LogReportTree())
}
}
}
activityHandler = ActivityHandler(this)
}

/**
Expand Down

0 comments on commit 4deb319

Please sign in to comment.