Giter Club home page Giter Club logo

geofire-ktx's Introduction

geofire-ktx

Kotlin extension functions for easy and idiomatic GeoQuerying on Firebase Database with GeoFire, on Android.

Why geofire-ktx?

GeoFire is built upon callbacks.

This library provides a series of extension functions that allow for a more idiomatic use of GeoQuery in Kotlin Android projects, by:

  1. Converting GeoQuery callbacks to Kotlin Flows
  2. Automatically mapping GeoLocation Flows to corresponding DataSnapshot in another database path.
  3. Automatically mapping GeoLocation Flows to corresponding data of type T in another database path.

Installation

On project-level build.gradle, add Jitpack repository:

allprojects {
  repositories {
    maven { url 'https://jitpack.io' }
  }
}

On app-level build.gradle, add dependency:

dependencies {
    implementation 'com.github.psteiger:geofire-ktx:0.6.0'
}

Usage

Given the GeoQuery:

val geoFire = GeoFire(Firebase.database.getReference("geofire"))
val geoLocation = GeoLocation(0.0, 0.0)
val radius = 100.0
val geoQuery = geoFire.queryAtLocation(geoLocation, radius)

GeoQuery as Flows

We recommend converting the GeoQuery to Flows for consuming the query result data. You can convert it to:

  1. Flow<Map<Key, GeoLocation>>
  2. Flow<Map<Key, LocationDataSnapshot>> // A pair of GeoLocation and DataSnapshot
  3. Flow<Map<Key, LocationData<T>> // A pair of GeoLocation and data of type T.

2 and 3 are for the use cases of querying GeoLocations to subsequently query for the related data on another database reference.

Querying for GeoLocations

val nearbyGeoLocations: Flow<Map<Key, GeoLocation>> = 
    geoQuery
        .asFlow()
        .flowOn(Dispatchers.IO)

Querying for locations and corresponding DataSnapshots with same keys in /users

val nearbyUsers: Flow<Map<Key, LocationDataSnapshot>> = 
    geoQuery
        .asFlow(Firebase.database.getReference("users"))
        .flowOn(Dispatchers.IO)
        .onEach { map ->
            map.onEach {
                val key = it.key
                val (geoLocation, dataSnapshot) = it.value
            }
        }

Querying for locations and corresponding users with same keys in /users

val nearbyUsers: Flow<Map<Key, LocationData<User>>> = 
    geoQuery
        .asTypedFlow<User>(Firebase.database.getReference("users"))
        .flowOn(Dispatchers.IO)
        .onEach { map ->
            map.onEach {
                val key = it.key
                val (geoLocation, user) = it.value
            }
        }

Notes

  1. In examples above, Key is just a typealias to String.
  2. All flows above are cold, and need to be collected so they start running (e.g. with launchIn())
  3. Consider converting the flows to SharedFlow (Flow<T>.shareIn()) or StateFlow (Flow<T>.stateIn()) if multiple collectors will be used.

Builder

If you still want to use GeoQuery callbacks and not Kotlin flows, we also offer a convenience builder for building the callback object in a more idiomatic way:

sealed class GeoQueryState { 
    data class Ready(val geoLocations: Map<Key, GeoLocation>) : GeoQueryState
    data class Cancelled(val exception: Exception) : GeoQueryState
}

private val _geoLocations = MutableSharedFlow<GeoQueryState>() // private mutable shared flow
val geoLocations = _geoLocations.asSharedFlow() // publicly exposed as read-only shared flow

geoQuery.addGeoQueryEventListener {
    val locations = mutableMapOf<Key, GeoLocation>()

    onKeyEntered { locations[this] = it }
    onKeyExited { locations.remove(this) }
    onKeyMoved { locations[this] = it }
    onGeoQueryReady { geoLocations.emit(GeoQueryState.Ready(locations.toMap())) }
    onGeoQueryError { geoLocations.emit(GeoQueryState.Cancelled(toException())) }
}

geofire-ktx's People

Contributors

psteiger avatar

Stargazers

Dmytro Goliy avatar Muh Arif Saputra avatar  avatar Dino Priyano avatar YJM avatar Pushpal Roy avatar Faisal Amir avatar  avatar Sejin Choi avatar  avatar  avatar Taylan Sabırcan avatar chonamdoo avatar  avatar Remy Benza avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.