Je suis en train de développer une application et d'enregistrer des chaînes comme postedAtTime
, postedBy
, postedOnDate
dans la base de données Firebase. Je veux enregistrer les coordonnées GeoFire dans le même nœud dans lequel toutes les chaînes ci-dessus sont enregistrées, afin que plus tard, je puisse faire une requête, facilement.
Voici le chemin vers lequel j'enregistre toutes les chaînes:
databaseReferenceHRequests = firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/");
Voici comment je le sauvegarde:
// 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);
}
Voici comment il est enregistré dans la base de données:
Ce que je veux, c'est enregistrer les coordonnées GeoFire dans le même nœud, qui est -KLIoLUsI0SpQZGpV1h4
ici. Il s'agit simplement d'un Push ID et il est généré de manière aléatoire.
Je l'ai essayé en donnant cette référence:
geoFire = new GeoFire(firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/"));
Et puis en le poussant avec d'autres éléments comme indiqué ci-dessus. Mais cela n'a enregistré que les coordonnées GeoFire et non les autres éléments sous le nœud requests
.
Alors, quelle devrait être ma référence GeoFire pour qu'elle soit enregistrée avec toutes les données dans le même nœud?
Qu'est-ce qui ne va pas ici? S'il vous plaît, faites-moi savoir.
La réponse de Frank est correcte, mais je veux donner un exemple. La structure de votre base de données devrait être comme ceci.
{
"items" : {
<itemId> : {
"someData" : "someData",
...
}
},
"items_location" : {
<itemId> : {
<geofireData> ...
}
}
}
Pour obtenir les données, vous devez d'abord faire GeoQuery à items_location
node, puis récupérez les données sur la méthode onKeyEntered
. Le paramètre key
est itemId
de mon exemple.
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
}
};
J'espère que cela t'aides.
MODIFIER Comment pousser l'élément et définir les données de feu géo.
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));
ÉDITEZ Enregistrez les données de l'article et les données de géofire en un seul appel d'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);
Lorsque vous utilisez Geofire, vous disposez de deux listes de données:
Vous utilisez les touches pour passer des résultats de Geoquery aux éléments réguliers. C'est pourquoi les événements pour Geofire sont appelés "Key Entered", "Key Exited", etc.
Essayer de les stocker dans un nœud est une mauvaise idée, car vous mélangez principalement des données statiques (les propriétés de vos éléments) avec des données très volatiles (les informations de géolocalisation). La séparation des deux conduit à de meilleures performances, c'est pourquoi Geofire les applique.
Bien qu'il puisse y avoir des cas d'utilisation où les propriétés et les géodonnées sont également dynamiques/statiques, GeoFire ne prend pas en charge la conservation des géodonnées et d'autres propriétés dans un seul emplacement.
Pour ceux qui viennent plus récemment à ce poste avec la même question, cela est possible avec la bibliothèque Geofirestore , qui prend en charge Geofire pour les applications construites au-dessus de la base de données Firebase Firestore.
Vous pouvez utiliser les fonctions Firebase pour l'entrer pour vous à chaque nouvelle entrée
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);
});
}
}