Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Shipping Apps Confidently with Firebase
Search
Subhrajyoti Sen
November 06, 2021
Programming
0
100
Shipping Apps Confidently with Firebase
Subhrajyoti Sen
November 06, 2021
Tweet
Share
More Decks by Subhrajyoti Sen
See All by Subhrajyoti Sen
Understanding Incremental Processing in the JVM World
subhrajyotisen
0
15
Updated Lessons from a KMP Developer's Toolkit
subhrajyotisen
0
49
Building Mobile Apps and Scaling them
subhrajyotisen
0
55
Compose Previews as a Power User
subhrajyotisen
1
190
Understanding WindowInsets
subhrajyotisen
0
240
Exploring a KMM Developer’s Toolkit
subhrajyotisen
1
250
Understanding WindowInsets - Android Worldwide
subhrajyotisen
0
360
Understanding WindowInsets
subhrajyotisen
1
220
Demystifying Styles and Themes
subhrajyotisen
0
260
Other Decks in Programming
See All in Programming
Docコメントで始める簡単ガードレール
keisukeikeda
1
120
nuget-server - あなたが必要だったNuGetサーバー
kekyo
PRO
0
250
クライアントワークでSREをするということ。あるいは事業会社におけるSREと同じこと・違うこと
nnaka2992
1
340
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
520
Agent Skills Workshop - AIへの頼み方を仕組み化する
gotalab555
15
8.8k
CDIの誤解しがちな仕様とその対処TIPS
futokiyo
0
220
文字コードの話
qnighy
44
17k
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
4
420
maplibre-gl-layers - 地図に移動体たくさん表示したい
kekyo
PRO
0
270
Go 1.26でのsliceのメモリアロケーション最適化 / Go 1.26 リリースパーティ #go126party
mazrean
1
400
AI時代のシステム設計:ドメインモデルで変更しやすさを守る設計戦略
masuda220
PRO
5
1k
Angular-Apps smarter machen mit Gen AI: Lokal und offlinefähig - Hands-on Workshop!
christianliebel
PRO
0
110
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
331
21k
Ethics towards AI in product and experience design
skipperchong
2
220
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
140
Joys of Absence: A Defence of Solitary Play
codingconduct
1
310
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
120
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.4k
ラッコキーワード サービス紹介資料
rakko
1
2.6M
From π to Pie charts
rasagy
0
150
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
150
Transcript
Shipping Apps Con dently with Firebase KeepTruckin Subhrajyoti Sen DevFest
Greece & Cyprus 2021 November 2021
Crashes
Crashlytics
Crashlytics • Automatic crash reporting
Crashlytics • • Automatic crash reporting But no limited to
crash reporting
Recording Non-fatal exceptions
Recording Non-fatal exceptions try { // some code can throw
an exception } catch (e: Exception) { Log.d(TAG, e.localizedMessage) }
Recording Non-fatal exceptions try { // some code can throw
an exception } catch (e: Exception) { Log.d(TAG, e.localizedMessage) }
Recording Non-fatal exceptions try { // some code can throw
an exception } catch (e: Exception) { FirebaseCrashlytics.getInstance().recordException(e) }
Recording Non-fatal exceptions private class CrashReportingTree : Timber.Tree() { }
Recording Non-fatal exceptions private class CrashReportingTree : Timber.Tree() { override
fun log(priority: Int, tag: String?, message: String, t: Throwable?) { } }
Recording Non-fatal exceptions private class CrashReportingTree : Timber.Tree() { override
fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (priority == Log.ERROR && t != null) { FirebaseCrashlytics.getInstance().recordException(t) } } }
Recording Non-fatal exceptions class MainApplication : Application() { override fun
onCreate() { super.onCreate() Timber.plant(CrashReportingTree()) } }
Recording Non-fatal exceptions try { // some code can throw
an exception } catch (e: Exception) { FirebaseCrashlytics.getInstance().recordException(e) }
Recording Non-fatal exceptions try { // some code can throw
an exception } catch (e: Exception) { Timber.e(e) }
Understanding Crashes Better
Analytics
Analytics • We normally use analytics in isolation from crash
reporting
Analytics • • We normally use analytics in isolation from
crash reporting Usually PMs check the analytics and Devs check the crashes
Analytics • • • We normally use analytics in isolation
from crash reporting Usually PMs check the analytics and Devs check the crashes What if you can combine them to get a full view?
Analytics
Analytics
Analytics binding.zoomImage.setOnClickListener { MixpanelAPI.track("Zoom button clicked") }
Analytics binding.zoomImage.setOnClickListener { MixpanelAPI.track("Zoom button clicked") FirebaseAnalytics.getInstance(context) .logEvent("Zoom button clicked",
mapOf("page", "map")) }
Analytics interface AnalyticsProvider { fun track( analyticEvent: String, properties: Map<String,
Any?>? = null ) }
Analytics class FirebaseAnalyticsProvider( private val rebaseAnalytics: FirebaseAnalytics ): AnalyticsProvider {
override fun track(analyticEvent: String, properties: Map<String, Any?>?) { rebaseAnalytics.logEvent(analyticEvent, properties) } }
Analytics class FirebaseAnalyticsProvider( private val rebaseAnalytics: FirebaseAnalytics ): AnalyticsProvider {
override fun track(analyticEvent: String, properties: Map<String, Any?>?) { rebaseAnalytics.logEvent(analyticEvent, properties) } }
Analytics class AnalyticsManager { private val analyticsProviders = mutableListOf<AnalyticsProvider>() fun
addProvider(provider: AnalyticsProvider) { analyticsProviders.add(provider) } }
Analytics class AnalyticsManager { //... fun track(analyticEvent: String, properties: Map<String,
Any?>?) { analyticsProviders.forEach { provider -> provider.track(analyticEvent, properties) } } }
Analytics binding.zoomImage.setOnClickListener { analyticsManager.logEvent( "Zoom button clicked", mapOf("page", "map") )
}
Feature Flags
What's a feature ag?
What's a feature ag? if (isNewFeatureEnabled) { // allow access
to shiny new feature } else { // prevent access to shiny new feature }
Use cases
Use cases • A/B Testing
Use cases • • A/B Testing Rolling out new features
Use cases • • • A/B Testing Rolling out new
features Rolling out rewrite of existing features
Use cases • • • • A/B Testing Rolling out
new features Rolling out rewrite of existing features Merge Work-in-progress features
Types of Feature Flags?
Types of Feature Flags? • Static
Types of Feature Flags? • • Static Decided at build
time
Types of Feature Flags? • • • Static Decided at
build time Based on things like versionCode, buildVariant, etc
Types of Feature Flags? • • • • Static Decided
at build time Based on things like versionCode, buildVariant, etc Dynamic
Types of Feature Flags? • • • • • Static
Decided at build time Based on things like versionCode, buildVariant, etc Dynamic Can be controlled at runtime either locally using dev settings
Types of Feature Flags? • • • • • •
Static Decided at build time Based on things like versionCode, buildVariant, etc Dynamic Can be controlled at runtime either locally using dev settings Or remotely via services like Firebase Remote Con g
None
Show me code!!
interface Con g { val key: String val default: Boolean
val description: String }
enum class FeatureFlags( override val key: String, override val default:
Boolean, override val description: String ): Con g
enum class FeatureFlags( override val key: String, override val default:
Boolean, override val description: String ): Con g { NEW_CHECKOUT_FLOW( "checkout_ ow_v2", true, "Enable checkout ow V2 for trending items" ) }
interface FeatureFlagProvider { fun getValue(featureFlag: FeatureFlag): Boolean }
class FirebaseFeatureFlagProvider: FeatureFlagProvider { private val remoteCon g = FirebaseRemoteCon
g.getInstance() override fun getValue(featureFlag: FeatureFlag): Boolean { return remoteCon g.getBoolean(featureFlag.key) } }
class RemoteCon gManager( private val featureFlagProvider: FeatureFlagProvider ) { fun
isFeatureEnabled(featureFlag: FeatureFlag) = featureFlagProvider.getValue(featureFlag) }
if (remoteCon gManager.isFeatureEnabled(NEW_CHECKOUT_FLOW)) { // allow access to shiny new
feature } else { // prevent access to shiny new feature }
Using Feature Flags effectively
Using Feature Flags effectively • De ne success metrics
Using Feature Flags effectively • • De ne success metrics
Less Crashes?
Using Feature Flags effectively • • • De ne success
metrics Less Crashes? Smoother experience?
Using Feature Flags effectively • • • • De ne
success metrics Less Crashes? Smoother experience? Implement using your Analytics library (like Mixpanel)
Using Feature Flags effectively • • • • • De
ne success metrics Less Crashes? Smoother experience? Implement using your Analytics library (like Mixpanel) Create dashboards to compare
@iamsubhrajyoti https://calendly.com/subhrajyotisen
Credits: UC Davis