2016-07-13 39 views
12

Sto sviluppando un'applicazione e salvando alcune stringhe come postedAtTime, postedBy, postedOnDate nel database di Firebase. Voglio salvare le coordinate GeoFire nello stesso nodo in cui sono salvate tutte le stringhe sopra, in modo che in seguito io possa fare una query, facilmente.Come salvare le coordinate GeoFire insieme ad altri oggetti nel database Firebase?

Ecco il percorso a cui sto risparmiando tutte le stringhe:

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

Questo è come mi sto salvandolo:

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

Ecco come è sempre salvato nel database:

database structure screenshot

Quello che voglio è quello di salvare le coordinate GeoFire nello stesso nodo, che è -KLIoLUsI0SpQZGpV1h4 qui. Questo è solo un ID push e viene generato casualmente.

ho provato dando questo riferimento:

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

E poi spingendola con altri elementi come mostrato sopra. Tuttavia, questo ha salvato solo le coordinate GeoFire e non gli altri elementi sotto il nodo requests.

Quindi, quale dovrebbe essere il mio riferimento GeoFire in modo che venga salvato insieme a tutti i dati nello stesso nodo?

Cosa sta succedendo qui? Per favore mi faccia sapere.

risposta

8

Quando si utilizza Geofire, ci sono due liste di dati:

  1. un elenco di elementi con le loro proprietà regolari
  2. un elenco di indici geohash e le loro chiavi associati, che si interrogate attraverso Geofire

Si utilizzano i tasti per passare dai risultati di Geoquery agli elementi normali. Ecco perché gli eventi per Geofire sono chiamati "Chiave inserita", "Chiave chiusa", ecc.

Cercare di archiviarli in un nodo è una cattiva idea, dal momento che stai mescolando principalmente dati statici (le proprietà dei tuoi oggetti) con dati altamente volatili (le informazioni sulla posizione geografica). Separare le due derivazioni per migliorare le prestazioni, motivo per cui Geofire la applica.

Mentre ci possono essere casi d'uso in cui le proprietà e i dati geografici sono ugualmente dinamici/statici, GeoFire non supporta il mantenimento dei dati geografici e di altre proprietà in un'unica posizione.

+0

Grazie per aver risposto, ma non sono sicuro di avere la risposta alla mia domanda. Voglio dire, come potrei recuperare solo quei messaggi dal database che si trova entro il raggio di 0,5 km dell'utente? Sto anche salvando la latitudine e la longitudine da dove sono stati pubblicati i post. Per favore, rendilo più chiaro, signore. –

+0

Geofire restituisce solo le chiavi dal nodo e quindi è necessario eseguire una query sul nodo delle proprietà regolari. Oppure Geofire restituisce anche i dati delle proprietà regolari? –

+0

@Frank puoi spiegare come memorizzare gli indici geohash e quale sarà la sua struttura –

29

La risposta di Frank è corretta, ma voglio fare un esempio. La struttura del tuo database dovrebbe essere così.

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

per ottenere i dati, in primo luogo è necessario fare GeoQuery a items_location nodo e quindi ottenere i dati sul metodo onKeyEntered. Il parametro key è itemId dal mio esempio.

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

Spero che questo aiuti.

MODIFICA Come spingere l'elemento e impostare i dati del 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)); 

EDIT Salvare i dati voce e dati geofire in chiamata uno 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); 
+0

Grazie per la risposta. Il problema è che il mio '' è un push id. Come posso tenerne traccia? Per favore mi faccia sapere. –

+0

Ho aggiornato la mia risposta – Wilik

+0

è necessario prima ottenere il 'itemId' e poi spingere i dati ... non posso spingere i dati prima e poi recuperare il' itemId' (pushId)? –

1

È possibile utilizzare funzioni Firebase di entrare per voi su ogni nuova voce

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