android firebase firebase-realtime-database geofire

android - ¿Cómo guardar coordenadas GeoFire junto con otros elementos en la base de datos de Firebase?



firebase-realtime-database (4)

Cuando usa Geofire, tiene dos listas de datos:

  1. una lista de artículos con sus propiedades regulares
  2. una lista de índices geohash y sus claves asociadas, que puede consultar a través de Geofire

Utiliza las teclas para pasar de los resultados de Geoquery a los elementos normales. Es por eso que los eventos para Geofire se denominan "Clave introducida", "Clave salida", etc.

Intentar almacenarlos en un nodo es una mala idea, ya que está mezclando principalmente datos estáticos (las propiedades de sus elementos) con datos altamente volátiles (la información de ubicación geográfica). La separación de los dos lleva a un mejor rendimiento, por lo que Geofire lo aplica.

Si bien puede haber casos de uso donde las propiedades y los datos geográficos son igualmente dinámicos / estáticos, GeoFire no admite mantener los datos geográficos y otras propiedades en una sola ubicación.

Estoy desarrollando una aplicación y guardando algunas cadenas como postedAtTime , postedBy , postedOnDate en la base de datos de Firebase. Quiero guardar las coordenadas GeoFire en el mismo nodo en el que se guardan todas las cadenas anteriores, para que luego pueda hacer consultas, fácilmente.

Aquí está el camino en el que estoy guardando todas las cadenas:

databaseReferenceHRequests = firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/");

Así es como lo estoy guardando:

// in onButtonClicked method: postNewRequest(null, imageUID, MainActivity.userName.getText().toString(), time, date, utcFormatDateTime, MainActivity.userEmail.getText().toString(), geoFire); // the method: public void postNewRequest(Bitmap bitmap, String imageUIDh, String postedBy, String postedAtTime, String postedOnDate, String utcFormatDateTime, String userEmail, GeoFire geoFire) { HRequest hRequest = new HelpRequest(null, imageUIDh, postedBy, postedAtTime, postedOnDate, utcFormatDateTime, userEmail, geoFire); databaseReferenceHRequests.push().setValue(hRequest); }

Así es como se guarda en la base de datos:

Lo que quiero es guardar las coordenadas GeoFire en el mismo nodo, que es -KLIoLUsI0SpQZGpV1h4 aquí. Esto es solo una ID de inserción y se genera aleatoriamente.

Lo intenté dando esta referencia:

geoFire = new GeoFire(firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/"));

Y luego empujándolo con otros elementos como se muestra arriba. Pero, esto solo guardó las coordenadas de GeoFire y no los otros elementos bajo las requests nodo.

Entonces, ¿cuál debería ser mi referencia GeoFire para que se guarde junto con todos los datos en el mismo nodo?

¿Qué está mal aquí? Por favor hagamelo saber.


La respuesta de Frank es correcta, pero quiero dar un ejemplo. La estructura de su base de datos debería ser así.

{ "items" : { <itemId> : { "someData" : "someData", ... } }, "items_location" : { <itemId> : { <geofireData> ... } } }

Para obtener los datos, primero debe hacer GeoQuery en el nodo items_location y luego obtener los datos en el método onKeyEntered . La key parámetro es itemId de mi ejemplo.

geoFire = new GeoFire(FirebaseDatabase.getInstance().getReference().child("items_location"); geoQuery = geoFire.queryAtLocation(geoLocation), radius); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { //retrieve data } };

Espero que esto ayude.

EDITAR Cómo empujar el elemento y configurar los datos de geofire.

String itemId = ref.child("items").push().getKey(); ref.child("items").child(itemId).setValue(item); geoFire = new GeoFire(ref.child("items_location")); geoFire.setLocation(itemId, new GeoLocation(lattitude, longitude));

EDITAR Guardar los datos del artículo y los datos de geofire en una llamada API

GeoHash geoHash = new GeoHash(new GeoLocation(latitude, longitude)); Map<String, Object> updates = new HashMap<>(); updates.put("items/" + itemId, item); updates.put("items_location/" + itemId + "/g", geoHash.getGeoHashString()); updates.put("items_location/" + itemId + "/l", Arrays.asList(latitude, longitude)); ref.updateChildren(updates);


Para aquellos que vinieron más recientemente a esta publicación con la misma pregunta, esto es posible con la biblioteca Geofirestore , que admite Geofire para aplicaciones creadas sobre la base de datos Firebase Firestore.


Puedes usar las funciones de Firebase para ingresarlo en cada nueva entrada

let functions = require(''firebase-functions''); let GeoFire = require(''geofire''); exports.testLocation = functions.database.ref(''/items/{item}'').onWrite(event => { let data = event.data.val(); console.log(data); console.log(event.params.item); if (data.location && data.location.coords) { console.log(''Update GeoFire''); let ref = event.data.adminRef.parent.parent.child(''/items_locations'')); let key = event.params.test; let location = [data.location.coords.latitude, data.location.coords.longitude]); let geoFire = new GeoFire(ref); geoFire.set(key, location).then(() => { console.log(''Update succesfull''); }).catch(error => { console.log(error); }); } }