google-cloud-firestorekotlin-multiplatformgeopointsgeofirestore

GeoFirestore in Kotlin Multi-platform Mobile


I am trying to learn more about KMM and while doing that I was trying to do some work with GeoPoints in Firebase. To access firebase in my KMM app, I am using gitLive SDK which has GeoPoint implementation as well. I have successfully created my documents and everything works.

data class User(
    val id: String = "",
    var name: String = "",
    var address: String = "",
    var geoPoint: GeoPoint
) {
     constructor() : this(geoPoint = GeoPoint(0.0, 0.0))
}

Until I wanted to query my data in Firestore based on location/radius. Upon my research realised Firebase has not implemented anything for that kind of queries expect GeoHashes and what was done when there was GeoFire in the realtime DB.

So I looked for a third party library and I came across GeoFireStore. It is very easy to use but it's an old implementation and does not support Firebase Kotlin SDK (gitLive for KMM). So the GeoPoint retrieved by the GeoFirestore is not compatible with Firebase Kotlin SDK. Hence when I try to deserialise the data in DocumentSnapShot, it fails (crashes) unless I do the mapping between data and class manually as follows:

private fun DocumentSnapshot.toUser(): User { // DocumentSnapshot.toUser is Android SDk
    val tmp_name = getField<String>("name")
    val tmp_address = getField<String>("address")
    val tmp_geoPoint = getGeoPoint("geoPoint") // Android SDK

    return User(
        tmp_name!!,
        tmp_address!!,
        GeoPoint(tmp_geoPoint!!.latitude, tmp_geoPoint.longitude) //KMM SDK
    )
}

My questions are:

  1. is there a better library than GeoFirestore?
  2. If not, how can I improve the help function without having to map it manually? My data class has a lot more data in it. Notice: There is a function DocumentSnapshot.toObject(valueType: Class) which the passed class should have the Android SDK implementation of GeoPoint. And that's where my app crashes.

Solution

  • You no longer need a geohash or other library to perform geoqueries on Firestore. Instead, you can just use a query with range and inequality filters on multiple fields to accomplish the same thing both simpler and more efficiently.

    For a long explanation of this with code samples and comparisons of efficiency between the approaches, see How to perform geoqueries on Firestore (somewhat) efficiently.

    You can also check the code in my testbed for the article in this StackBlitz: https://stackblitz.com/edit/geofire-geoquery-2024