Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[David Vávra] Firebase + Kotlin + RxJava + MVP: Practical Tips

[David Vávra] Firebase + Kotlin + RxJava + MVP: Practical Tips

Presentation from GDG DevFest Ukraine 2016.
Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

September 10, 2016
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. Firebase + Kotlin + Rx + MVP 8 Practical Tips

    David Vávra Founder/CEO/Dev Lead @ Step Up Labs
  2. #dfua 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() } #1 How can a presenter survive config change? http://bit.ly/presenterrotation
  3. #dfua class PresenterLoader<T : Presenter<out MvpView>>(context: Context, val mFactory: 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 } #1 How can a presenter survive config change? http://bit.ly/presenterrotation
  4. #dfua 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) } #2 How to access Realtime Database in Rx? http://bit.ly/rxfirebase
  5. #dfua fun observeLoaded(query: DatabaseQuery): Observable<ListEvent> { return Observable.fromAsync<ListEvent>({ query.addListenerForSingleValueEvent(object :

    ValueEventListener { override fun onCancelled(databaseError: DatabaseError) { it.onError(RuntimeException(databaseError.message)) } override fun onDataChange(dataSnapshot: DataSnapshot) { it.onNext(ListEvent(dataSnapshot, ListEvent.LIST_LOADED, null)) } }) it.setCancellation { query.removeEventListener(listener) } }, AsyncEmitter.BackpressureMode.BUFFER) } #3 How to detect that a list loaded?
  6. #dfua "transactions": { "group_id_1": { "expense_id_1": { ... } }

    }, "groups": { "group_id_1": { "name": "Dogfood" } }, #4 How to structure Realtime Database data? "permissions": { "group_id_1": { "user_id_1": { "level" : 30 } } }, "userGroups": { "user_id_1": { "group_id_1": { "order": 1 }, "group_id_2": { "order": 2 } } } http://bit.ly/firebasestructure
  7. #dfua "transactions": { "group_id_1": { "expense_id_1": { "items": [ {

    "amount": "200.33", "name": "Pivo", "paidFor": [ { "memberId": "member_id_1", "weight": "1" }, { "memberId": "member_id_2", "weight": "2.3" } ], } ], ... #5 Is it OK to use arrays? http://bit.ly/firebasearrays