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

Estoy desarrollando una aplicación y guardando algunas cadenas como postedAtTime , postedBy , postedOnDate en la base de datos de Firebase. Quiero guardar las coordenadas de 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 hacia el cual 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 cómo se guarda en la base de datos:

captura de pantalla de la estructura

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

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. Sin embargo, esto solo guardaba las coordenadas 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" : {  : { "someData" : "someData", ... } }, "items_location" : {  : {  ... } } } 

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 establecer 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 Guarda los datos del elemento y los datos del geofire en una llamada a la API

 GeoHash geoHash = new GeoHash(new GeoLocation(latitude, longitude)); Map 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); 

Cuando utilizas Geofire, tienes 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 consulta a través de Geofire

Utiliza las teclas para obtener los resultados de Geoquery a los artículos normales. Es por eso que los eventos para Geofire se llaman “Key Enterred”, “Key Exited”, etc.

Intentar almacenarlos en un nodo es una mala idea, ya que está mezclando la mayoría de los datos estáticos (las propiedades de sus elementos) con datos altamente volátiles (la información de geolocalización). La separación de los dos conduce a un mejor rendimiento, por lo que Geofire lo impone.

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

Puede 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); }); } } 

Para quienes más recientemente llegan a esta publicación con la misma pregunta, esto es posible con la biblioteca Geofirestre , que es compatible con Geofire para aplicaciones creadas sobre la base de datos de Firebase Firestre.