SlideShare uma empresa Scribd logo
1 de 25
Baixar para ler offline
Firebase + Kotlin + Rx + MVP
David Vávra
@vavradav, +David Vávra, medium.com/@david.vavra
About me
Founder&CEO at
Android and backend hacker of Settle Up
Google Developer Expert for
Organizer at GDG Prague
Settle Up
Redesigned Settle Up
Architecture choices
Firebase
Realtime
Database
Own server Realm
Kotlin Java
MVP MVVM
Challenges & how we solved them
How to structure
data in Firebase
Realtime
Database?
{
"transactions": {
"group_id_1": {
"expense_id_1": {
...
}
}
},
"groups": {
"group_id_1": {
"name": "India trip",
...
}
},
"permissions": {
"group_id_1": {
"user_id_1": {
"level" : 30
}
}
},
"usersGroups": {
"user_id_1": {
"group_id_1": true,
"group_id_2": true
}
}
}
http://bit.ly/firebasestructure
How can presenter survive configuration changes
abstract class BaseFragment<P : Presenter<V>, V : MvpView> : Fragment(), LoaderManager.LoaderCallbacks<P> {
private var mPresenter: P? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
loaderManager.initLoader(PRESENTER_LOADER_ID, Bundle(), this)
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<P>? {
return PresenterLoader(activity, getPresenterFactory())
}
override fun onLoadFinished(loader: Loader<P>, presenter: P) {
mPresenter = presenter
}
override fun onResume() {
mPresenter?.attachView(this as V)
}
override fun onPause() {
mPresenter?.detachView()
}
}
http://bit.ly/presenterrotation
How can presenter survive configuration changes
class PresenterLoader<T : Presenter<out MvpView>>(context: Context, val factory: PresenterFactory<T>) : Loader<T>(context) {
private var presenter: T? = null
override fun onStartLoading() {
if (presenter != null) {
deliverResult(presenter)
} else {
forceLoad()
}
}
override fun onForceLoad() {
presenter = mFactory.create()
presenter?.onCreatedByLoader()
deliverResult(presenter)
}
override fun onReset() {
presenter?.onDestroyedByLoader()
presenter = null
}
}
http://bit.ly/presenterrotation
How to coordinate multiple async calls to Firebase Realtime Database
fun observe(query: DatabaseQuery): Observable<DataSnapshot> {
return Observable.fromAsync<DataSnapshot>({
val listener = query.addValueEventListener(object : ValueEventListener {
override fun onCancelled(databaseError: DatabaseError) {
it.onError(RuntimeException(databaseError.message))
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
it.onNext(dataSnapshot)
}
})
it.setCancellation { query.removeEventListener(listener) }
}, AsyncEmitter.BackpressureMode.BUFFER)
}
http://bit.ly/rxfirebase
How to coordinate multiple async calls to Firebase Realtime Database
object DatabaseRead {
fun getUserGroupColor(groupId: String): Observable<String> {
return ObjectQuery().apply { path = "userGroups/${Auth.getUserId()}/$groupId/color" }
.observe()
.toPrimitiveObservable(String::class.java)
}
fun getMember(groupId: String, memberId: String): Observable<Member> {
return ObjectQuery().apply { path = "members/$groupId/$memberId" }
.observe()
.toObjectObservable(Member::class.java)
}
}
How to coordinate multiple async calls to Firebase Realtime Database
private fun <T> load(observable: Observable<T>, displayToView: (T) -> Unit) {
val data = PresenterData(observable, displayToView)
data.subscription = data.observable.subscribe({
data.cachedValue = it
if (isViewAttached) {
data.displayToView(it)
}
}, {
showError(it)
})
mDataList.add(data)
}
How to coordinate multiple async calls to Firebase Realtime Database
fun loadMultiple(observables: List<Observable<out Any>>, displayToView: (Array<Any>) -> Unit) {
val data = PresenterMultipleData(observables, displayToView)
Observable.combineLatest(observables, {
it
}).subscribe({
data.cachedValue = it
if (isViewAttached) {
data.displayToView(it)
}
}, {
showError(it)
})
mMultipleDataList.add(data)
}
Concrete example - Member detail screen
{
"members": {
"group_id_2": {
"member_id_1": {
"bankAccount": "532224564654/0100",
"defaultWeight": "1",
"name": "David",
"photoUrl": "https://lh3.googleusercontent.com/...jpg"
}
}
},
"userGroups": {
"user_id_1": {
"group_id_2": {
"color": "#00BCD4",
"member": "member_id_1"
}
}
}
Concrete example - Member detail screen
class MemberDetailPresenter(val groupId: String, val memberId: String) : BasePresenter<MemberDetailMvpView>() {
override fun onCreatedByLoader() {
loadOnce(DatabaseRead.getUserGroupColor(groupId), {
getView().setGroupColor(Color.parseColor(it))
})
loadMultiple(listOf(DatabaseRead.getMember(groupId, memberId), DatabaseRead.getUserMember(groupId)) {
val member = it[0] as Member
val userMember = it[1] as String?
getView().setMember(member, member.id == userMember)
})
}
}
Concrete example - Member detail screen
class MemberDetailActivity : BaseActivity<MemberDetailPresenter, MemberDetailMvpView>(), MemberDetailMvpView {
override fun getLayoutRes(): Int {
return R.layout.activity_member_detail
}
override fun getPresenterFactory(): PresenterFactory<MemberDetailPresenter> {
return MemberDetailPresenter.Factory(getGroupId(), getMemberId())
}
override fun setMember(member: Member, thisIsMe: Boolean) {
vName.setText(member.name)
vThisIsMe.isChecked = thisIsMe
}
override fun setGroupColor(color: Int) {
vHeader.setBackgroundColor(color)
}
}
How does Firebase pricing affect
monetization?
Realtime Database:
$5/stored GB monthly
Storage:
$0.026/stored GB monthly
Our monetization:
Freemium
● Subscription
● Or free app with video ads
http://bit.ly/firebasepricing
Windows support?
https://github.com/step-up-labs/firebase-database-dotnet
https://github.com/step-up-labs/firebase-authentication-dotnet
https://github.com/step-up-labs/firebase-storage-dotnet
TL;DR
Firebase is great
Build new apps in Kotlin
Use MVP architecture, Presenter should survive orientation change with Loader
RxJava is great for combining multiple async calls to Firebase
Think about database structure and monetization before you start building
Q&A
Follow me:
twitter.com/vavradav
medium.com/@david.vavra

Mais conteúdo relacionado

Mais procurados

Working with NoSQL in a SQL Database (XDevApi)
Working with NoSQL in a SQL Database (XDevApi)Working with NoSQL in a SQL Database (XDevApi)
Working with NoSQL in a SQL Database (XDevApi)Lior Altarescu
 
FleetDB A Schema-Free Database in Clojure
FleetDB A Schema-Free Database in ClojureFleetDB A Schema-Free Database in Clojure
FleetDB A Schema-Free Database in Clojureelliando dias
 
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...MongoDB
 
Jan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingJan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingGeorge Ang
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analyticsMongoDB
 
Akka with Scala
Akka with ScalaAkka with Scala
Akka with ScalaOto Brglez
 
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...MongoDB
 
Easy Scaling with Open Source Data Structures, by Talip Ozturk
Easy Scaling with Open Source Data Structures, by Talip OzturkEasy Scaling with Open Source Data Structures, by Talip Ozturk
Easy Scaling with Open Source Data Structures, by Talip OzturkZeroTurnaround
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Sirar Salih
 
Heroku Postgres Cloud Database Webinar
Heroku Postgres Cloud Database WebinarHeroku Postgres Cloud Database Webinar
Heroku Postgres Cloud Database WebinarSalesforce Developers
 
MySQL flexible schema and JSON for Internet of Things
MySQL flexible schema and JSON for Internet of ThingsMySQL flexible schema and JSON for Internet of Things
MySQL flexible schema and JSON for Internet of ThingsAlexander Rubin
 

Mais procurados (12)

Working with NoSQL in a SQL Database (XDevApi)
Working with NoSQL in a SQL Database (XDevApi)Working with NoSQL in a SQL Database (XDevApi)
Working with NoSQL in a SQL Database (XDevApi)
 
FleetDB A Schema-Free Database in Clojure
FleetDB A Schema-Free Database in ClojureFleetDB A Schema-Free Database in Clojure
FleetDB A Schema-Free Database in Clojure
 
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...
MongoDB World 2018: Time for a Change Stream - Using MongoDB Change Streams t...
 
Jan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingJan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World Setting
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analytics
 
Akka with Scala
Akka with ScalaAkka with Scala
Akka with Scala
 
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
MongoDB .local Munich 2019: Best Practices for Working with IoT and Time-seri...
 
Easy Scaling with Open Source Data Structures, by Talip Ozturk
Easy Scaling with Open Source Data Structures, by Talip OzturkEasy Scaling with Open Source Data Structures, by Talip Ozturk
Easy Scaling with Open Source Data Structures, by Talip Ozturk
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
 
Heroku Postgres Cloud Database Webinar
Heroku Postgres Cloud Database WebinarHeroku Postgres Cloud Database Webinar
Heroku Postgres Cloud Database Webinar
 
Composable caching
Composable cachingComposable caching
Composable caching
 
MySQL flexible schema and JSON for Internet of Things
MySQL flexible schema and JSON for Internet of ThingsMySQL flexible schema and JSON for Internet of Things
MySQL flexible schema and JSON for Internet of Things
 

Semelhante a David Vávra: Firebase + Kotlin + RX + MVP

Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of usOSCON Byrum
 
REST more with json-api and fractal
REST more with json-api and fractalREST more with json-api and fractal
REST more with json-api and fractalBoyan Yordanov
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkIndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomerzefhemel
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networkingVitali Pekelis
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecturezefhemel
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代Shengyou Fan
 
Spark Cassandra Connector: Past, Present, and Future
Spark Cassandra Connector: Past, Present, and FutureSpark Cassandra Connector: Past, Present, and Future
Spark Cassandra Connector: Past, Present, and FutureRussell Spitzer
 
DataStax: Spark Cassandra Connector - Past, Present and Future
DataStax: Spark Cassandra Connector - Past, Present and FutureDataStax: Spark Cassandra Connector - Past, Present and Future
DataStax: Spark Cassandra Connector - Past, Present and FutureDataStax Academy
 
Progressive Enhancment with Rails and React
Progressive Enhancment with Rails and ReactProgressive Enhancment with Rails and React
Progressive Enhancment with Rails and ReactTyler Johnston
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentationValdis Iljuconoks
 
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)camunda services GmbH
 

Semelhante a David Vávra: Firebase + Kotlin + RX + MVP (20)

Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
REST more with json-api and fractal
REST more with json-api and fractalREST more with json-api and fractal
REST more with json-api and fractal
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
Kitura Todolist tutorial
Kitura Todolist tutorialKitura Todolist tutorial
Kitura Todolist tutorial
 
LiveOps para games usando o Firebase
LiveOps para games usando o FirebaseLiveOps para games usando o Firebase
LiveOps para games usando o Firebase
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networking
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
 
Spark Cassandra Connector: Past, Present, and Future
Spark Cassandra Connector: Past, Present, and FutureSpark Cassandra Connector: Past, Present, and Future
Spark Cassandra Connector: Past, Present, and Future
 
DataStax: Spark Cassandra Connector - Past, Present and Future
DataStax: Spark Cassandra Connector - Past, Present and FutureDataStax: Spark Cassandra Connector - Past, Present and Future
DataStax: Spark Cassandra Connector - Past, Present and Future
 
mobl
moblmobl
mobl
 
Progressive Enhancment with Rails and React
Progressive Enhancment with Rails and ReactProgressive Enhancment with Rails and React
Progressive Enhancment with Rails and React
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentation
 
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
 

Mais de mdevtalk

Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftu
Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve SwiftuJan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftu
Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftumdevtalk
 
Jarda Machaň: Proč je dobré míti Developer Evangelistu
Jarda Machaň: Proč je dobré míti Developer EvangelistuJarda Machaň: Proč je dobré míti Developer Evangelistu
Jarda Machaň: Proč je dobré míti Developer Evangelistumdevtalk
 
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOS
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOSPavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOS
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOSmdevtalk
 
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...mdevtalk
 
Michal Havryluk: How To Speed Up Android Gradle Builds
Michal Havryluk: How To Speed Up Android Gradle BuildsMichal Havryluk: How To Speed Up Android Gradle Builds
Michal Havryluk: How To Speed Up Android Gradle Buildsmdevtalk
 
Vladislav Iliushin: Dark side of IoT
Vladislav Iliushin: Dark side of IoTVladislav Iliushin: Dark side of IoT
Vladislav Iliushin: Dark side of IoTmdevtalk
 
Georgiy Shur: Bring onboarding to life
Georgiy Shur: Bring onboarding to lifeGeorgiy Shur: Bring onboarding to life
Georgiy Shur: Bring onboarding to lifemdevtalk
 
David Bilík: Anko – modern way to build your layouts?
David Bilík: Anko – modern way to build your layouts?David Bilík: Anko – modern way to build your layouts?
David Bilík: Anko – modern way to build your layouts?mdevtalk
 
Maxim Zaks: Deep dive into data serialisation
Maxim Zaks: Deep dive into data serialisationMaxim Zaks: Deep dive into data serialisation
Maxim Zaks: Deep dive into data serialisationmdevtalk
 
Nikita Tuk: Handling background processes in iOS: problems & solutions
Nikita Tuk: Handling background processes in iOS: problems & solutionsNikita Tuk: Handling background processes in iOS: problems & solutions
Nikita Tuk: Handling background processes in iOS: problems & solutionsmdevtalk
 
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na AndroiduMilan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na Androidumdevtalk
 
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundů
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundůTomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundů
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundůmdevtalk
 
Adam Šimek: Optimalizace skrolování, RecyclerView
Adam Šimek: Optimalizace skrolování, RecyclerViewAdam Šimek: Optimalizace skrolování, RecyclerView
Adam Šimek: Optimalizace skrolování, RecyclerViewmdevtalk
 
Paul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & syncPaul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & syncmdevtalk
 
Charles Du: Introduction to Mobile UX Design
Charles Du: Introduction to Mobile UX DesignCharles Du: Introduction to Mobile UX Design
Charles Du: Introduction to Mobile UX Designmdevtalk
 
Honza Dvorský: Swift Package Manager
Honza Dvorský: Swift Package ManagerHonza Dvorský: Swift Package Manager
Honza Dvorský: Swift Package Managermdevtalk
 
David Bureš - Xamarin, IoT a Azure
David Bureš - Xamarin, IoT a AzureDavid Bureš - Xamarin, IoT a Azure
David Bureš - Xamarin, IoT a Azuremdevtalk
 
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptat
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptatDominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptat
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptatmdevtalk
 
Jiří Dutkevič: Ochrana citlivých dat v iOS
Jiří Dutkevič: Ochrana citlivých dat v iOSJiří Dutkevič: Ochrana citlivých dat v iOS
Jiří Dutkevič: Ochrana citlivých dat v iOSmdevtalk
 
Petr Dvořák: Push notifikace ve velkém
Petr Dvořák: Push notifikace ve velkémPetr Dvořák: Push notifikace ve velkém
Petr Dvořák: Push notifikace ve velkémmdevtalk
 

Mais de mdevtalk (20)

Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftu
Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve SwiftuJan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftu
Jan Čislinský: Seznámení se Sourcery aneb Základy metaprogramování ve Swiftu
 
Jarda Machaň: Proč je dobré míti Developer Evangelistu
Jarda Machaň: Proč je dobré míti Developer EvangelistuJarda Machaň: Proč je dobré míti Developer Evangelistu
Jarda Machaň: Proč je dobré míti Developer Evangelistu
 
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOS
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOSPavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOS
Pavel Cvetler: Jeden kód, co vládne všem? Žádný problém pro Android i iOS
 
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...
Anastasiia Vixentael: 10 things you need to know before implementing cryptogr...
 
Michal Havryluk: How To Speed Up Android Gradle Builds
Michal Havryluk: How To Speed Up Android Gradle BuildsMichal Havryluk: How To Speed Up Android Gradle Builds
Michal Havryluk: How To Speed Up Android Gradle Builds
 
Vladislav Iliushin: Dark side of IoT
Vladislav Iliushin: Dark side of IoTVladislav Iliushin: Dark side of IoT
Vladislav Iliushin: Dark side of IoT
 
Georgiy Shur: Bring onboarding to life
Georgiy Shur: Bring onboarding to lifeGeorgiy Shur: Bring onboarding to life
Georgiy Shur: Bring onboarding to life
 
David Bilík: Anko – modern way to build your layouts?
David Bilík: Anko – modern way to build your layouts?David Bilík: Anko – modern way to build your layouts?
David Bilík: Anko – modern way to build your layouts?
 
Maxim Zaks: Deep dive into data serialisation
Maxim Zaks: Deep dive into data serialisationMaxim Zaks: Deep dive into data serialisation
Maxim Zaks: Deep dive into data serialisation
 
Nikita Tuk: Handling background processes in iOS: problems & solutions
Nikita Tuk: Handling background processes in iOS: problems & solutionsNikita Tuk: Handling background processes in iOS: problems & solutions
Nikita Tuk: Handling background processes in iOS: problems & solutions
 
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na AndroiduMilan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
 
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundů
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundůTomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundů
Tomáš Kohout: Jak zrychlit iOS vývoj pomocí Swift playgoundů
 
Adam Šimek: Optimalizace skrolování, RecyclerView
Adam Šimek: Optimalizace skrolování, RecyclerViewAdam Šimek: Optimalizace skrolování, RecyclerView
Adam Šimek: Optimalizace skrolování, RecyclerView
 
Paul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & syncPaul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & sync
 
Charles Du: Introduction to Mobile UX Design
Charles Du: Introduction to Mobile UX DesignCharles Du: Introduction to Mobile UX Design
Charles Du: Introduction to Mobile UX Design
 
Honza Dvorský: Swift Package Manager
Honza Dvorský: Swift Package ManagerHonza Dvorský: Swift Package Manager
Honza Dvorský: Swift Package Manager
 
David Bureš - Xamarin, IoT a Azure
David Bureš - Xamarin, IoT a AzureDavid Bureš - Xamarin, IoT a Azure
David Bureš - Xamarin, IoT a Azure
 
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptat
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptatDominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptat
Dominik Veselý - Vše co jste kdy chtěli vědět o CI a báli jste se zeptat
 
Jiří Dutkevič: Ochrana citlivých dat v iOS
Jiří Dutkevič: Ochrana citlivých dat v iOSJiří Dutkevič: Ochrana citlivých dat v iOS
Jiří Dutkevič: Ochrana citlivých dat v iOS
 
Petr Dvořák: Push notifikace ve velkém
Petr Dvořák: Push notifikace ve velkémPetr Dvořák: Push notifikace ve velkém
Petr Dvořák: Push notifikace ve velkém
 

Último

Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesChandrakantDivate1
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsChandrakantDivate1
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...nishasame66
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsChandrakantDivate1
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfCWS Technology
 

Último (6)

Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdf
 

David Vávra: Firebase + Kotlin + RX + MVP

  • 1.
  • 2.
  • 3. Firebase + Kotlin + Rx + MVP David Vávra @vavradav, +David Vávra, medium.com/@david.vavra
  • 4. About me Founder&CEO at Android and backend hacker of Settle Up Google Developer Expert for Organizer at GDG Prague
  • 11. Challenges & how we solved them
  • 12. How to structure data in Firebase Realtime Database? { "transactions": { "group_id_1": { "expense_id_1": { ... } } }, "groups": { "group_id_1": { "name": "India trip", ... } }, "permissions": { "group_id_1": { "user_id_1": { "level" : 30 } } }, "usersGroups": { "user_id_1": { "group_id_1": true, "group_id_2": true } } } http://bit.ly/firebasestructure
  • 13. How can presenter survive configuration changes abstract class BaseFragment<P : Presenter<V>, V : MvpView> : Fragment(), LoaderManager.LoaderCallbacks<P> { private var mPresenter: P? = null override fun onActivityCreated(savedInstanceState: Bundle?) { loaderManager.initLoader(PRESENTER_LOADER_ID, Bundle(), this) } override fun onCreateLoader(id: Int, args: Bundle): Loader<P>? { return PresenterLoader(activity, getPresenterFactory()) } override fun onLoadFinished(loader: Loader<P>, presenter: P) { mPresenter = presenter } override fun onResume() { mPresenter?.attachView(this as V) } override fun onPause() { mPresenter?.detachView() } } http://bit.ly/presenterrotation
  • 14. How can presenter survive configuration changes class PresenterLoader<T : Presenter<out MvpView>>(context: Context, val factory: PresenterFactory<T>) : Loader<T>(context) { private var presenter: T? = null override fun onStartLoading() { if (presenter != null) { deliverResult(presenter) } else { forceLoad() } } override fun onForceLoad() { presenter = mFactory.create() presenter?.onCreatedByLoader() deliverResult(presenter) } override fun onReset() { presenter?.onDestroyedByLoader() presenter = null } } http://bit.ly/presenterrotation
  • 15. How to coordinate multiple async calls to Firebase Realtime Database fun observe(query: DatabaseQuery): Observable<DataSnapshot> { return Observable.fromAsync<DataSnapshot>({ val listener = query.addValueEventListener(object : ValueEventListener { override fun onCancelled(databaseError: DatabaseError) { it.onError(RuntimeException(databaseError.message)) } override fun onDataChange(dataSnapshot: DataSnapshot) { it.onNext(dataSnapshot) } }) it.setCancellation { query.removeEventListener(listener) } }, AsyncEmitter.BackpressureMode.BUFFER) } http://bit.ly/rxfirebase
  • 16. How to coordinate multiple async calls to Firebase Realtime Database object DatabaseRead { fun getUserGroupColor(groupId: String): Observable<String> { return ObjectQuery().apply { path = "userGroups/${Auth.getUserId()}/$groupId/color" } .observe() .toPrimitiveObservable(String::class.java) } fun getMember(groupId: String, memberId: String): Observable<Member> { return ObjectQuery().apply { path = "members/$groupId/$memberId" } .observe() .toObjectObservable(Member::class.java) } }
  • 17. How to coordinate multiple async calls to Firebase Realtime Database private fun <T> load(observable: Observable<T>, displayToView: (T) -> Unit) { val data = PresenterData(observable, displayToView) data.subscription = data.observable.subscribe({ data.cachedValue = it if (isViewAttached) { data.displayToView(it) } }, { showError(it) }) mDataList.add(data) }
  • 18. How to coordinate multiple async calls to Firebase Realtime Database fun loadMultiple(observables: List<Observable<out Any>>, displayToView: (Array<Any>) -> Unit) { val data = PresenterMultipleData(observables, displayToView) Observable.combineLatest(observables, { it }).subscribe({ data.cachedValue = it if (isViewAttached) { data.displayToView(it) } }, { showError(it) }) mMultipleDataList.add(data) }
  • 19. Concrete example - Member detail screen { "members": { "group_id_2": { "member_id_1": { "bankAccount": "532224564654/0100", "defaultWeight": "1", "name": "David", "photoUrl": "https://lh3.googleusercontent.com/...jpg" } } }, "userGroups": { "user_id_1": { "group_id_2": { "color": "#00BCD4", "member": "member_id_1" } } }
  • 20. Concrete example - Member detail screen class MemberDetailPresenter(val groupId: String, val memberId: String) : BasePresenter<MemberDetailMvpView>() { override fun onCreatedByLoader() { loadOnce(DatabaseRead.getUserGroupColor(groupId), { getView().setGroupColor(Color.parseColor(it)) }) loadMultiple(listOf(DatabaseRead.getMember(groupId, memberId), DatabaseRead.getUserMember(groupId)) { val member = it[0] as Member val userMember = it[1] as String? getView().setMember(member, member.id == userMember) }) } }
  • 21. Concrete example - Member detail screen class MemberDetailActivity : BaseActivity<MemberDetailPresenter, MemberDetailMvpView>(), MemberDetailMvpView { override fun getLayoutRes(): Int { return R.layout.activity_member_detail } override fun getPresenterFactory(): PresenterFactory<MemberDetailPresenter> { return MemberDetailPresenter.Factory(getGroupId(), getMemberId()) } override fun setMember(member: Member, thisIsMe: Boolean) { vName.setText(member.name) vThisIsMe.isChecked = thisIsMe } override fun setGroupColor(color: Int) { vHeader.setBackgroundColor(color) } }
  • 22. How does Firebase pricing affect monetization? Realtime Database: $5/stored GB monthly Storage: $0.026/stored GB monthly Our monetization: Freemium ● Subscription ● Or free app with video ads http://bit.ly/firebasepricing
  • 24. TL;DR Firebase is great Build new apps in Kotlin Use MVP architecture, Presenter should survive orientation change with Loader RxJava is great for combining multiple async calls to Firebase Think about database structure and monetization before you start building