Я пытаюсь узнать больше о KMM и при этом пытаюсь поработать с GeoPoints в Firebase. Чтобы получить доступ к Firebase в моем приложении KMM, я использую gitLive SDK, который также имеет реализацию GeoPoint. Я успешно создал свои документы, и все работает.
data class User(
val id: String = "",
var name: String = "",
var address: String = "",
var geoPoint: GeoPoint
) {
constructor() : this(geoPoint = GeoPoint(0.0, 0.0))
}
Пока я не захотел запросить свои данные в Firestore на основе местоположения/радиуса. В результате моего исследования выяснилось, что Firebase ничего не реализовала для таких запросов, кроме GeoHashes и того, что было сделано, когда в базе данных реального времени был GeoFire.
Поэтому я поискал стороннюю библиотеку и наткнулся на GeoFireStore. Он очень прост в использовании, но это старая реализация, которая не поддерживает Firebase Kotlin SDK (gitLive для KMM). Таким образом, GeoPoint, полученный GeoFirestore, несовместим с Firebase Kotlin SDK. Следовательно, когда я пытаюсь десериализовать данные в DocumentSnapShot, происходит сбой (сбой), если я не выполняю сопоставление между данными и классом вручную следующим образом:
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
)
}
Мои вопросы:
Вам больше не нужен геохеш или другая библиотека для выполнения геозапросов в Firestore. Вместо этого вы можете просто использовать запрос с фильтрами диапазона и неравенства в нескольких полях, чтобы выполнить ту же самую задачу проще и эффективнее.
Подробное объяснение этого с примерами кода и сравнением эффективности разных подходов см. в разделе Как (в некоторой степени) эффективно выполнять геозапросы в Firestore.
Вы также можете проверить код статьи в StackBlitz на моем тестовом стенде: https://stackblitz.com/edit/geofire-geoquery-2024
Еще один вопрос: как мне рассчитать длину/широту поля соединения, если я использую свое местоположение пользователя? вы не можете просто добавить к нему радиус, поскольку долгота/широта — это угол!
JavaScript where("field", "> = ", ...)
действительно эквивалентен whereGreaterThanOrEqualTo("field", ...)
в Котлине. Чтобы вычислить ограничивающую рамку, проверьте строку 85–118 в этом воспроизведении: stackblitz.com/edit/geofire-geoquery-2024?file=index.js%3AL118
Я принимаю ваше решение как свой ответ, поскольку оно работает и является более общим и родным, чем мое собственное решение. Что я хочу знать сейчас, так это то, что насчет GeoPoint и что, если в будущем появятся более сложные пространственные запросы?
Ух ты, какую хорошую статью ты написал. Спасибо друг! Пара вещей:
where
следует заменить наwhereGreaterThanOrEqualTo
! Работает ли он с Firebase Kotlin SDK?Geopoint
поле тогда бесполезно?!