アプリを開発し、postedAtTime
、postedBy
、postedOnDate
などの文字列をFirebaseデータベースに保存しています。上記のすべての文字列が保存されている同じノードにGeoFire座標を保存して、後で簡単にクエリを実行できるようにします。
すべての文字列を保存するパスは次のとおりです。
databaseReferenceHRequests = firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/");
これは私がそれを保存する方法です:
// 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);
}
データベースに保存する方法は次のとおりです。
必要なのは、同じノードにGeoFire座標を保存することです。これは-KLIoLUsI0SpQZGpV1h4
ここに。これは単なるプッシュIDであり、ランダムに生成されます。
私はこの参照を与えて試しました:
geoFire = new GeoFire(firebaseDatabase.getReferenceFromUrl("https://appName-e1a35.firebaseio.com/requests/"));
次に、上記のように他のアイテムでプッシュします。ただし、これはGeoFire座標のみを保存し、ノードrequests
の下の他のアイテムは保存しません。
それで、同じノード内のすべてのデータとともに保存されるように、GeoFire参照はどうあるべきでしょうか?
ここで何が問題になっていますか?私にお知らせください。
フランクの答えは正しいですが、例を挙げたいと思います。データベース構造は次のようになります。
{
"items" : {
<itemId> : {
"someData" : "someData",
...
}
},
"items_location" : {
<itemId> : {
<geofireData> ...
}
}
}
データを取得するには、最初にitems_location
ノードでGeoQueryを実行してから、onKeyEntered
メソッドでデータを取得する必要があります。パラメーターkey
は、私の例ではitemId
です。
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
}
};
お役に立てれば。
[〜#〜] edit [〜#〜]アイテムをプッシュして、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 [〜#〜] 1回のAPI呼び出しでアイテムデータとgeofireデータを保存する
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);
Geofireを使用する場合、2つのデータリストがあります。
キーを使用して、Geoqueryの結果から通常のアイテムを取得します。そのため、Geofireのイベントは「キー入力」、「キー終了」などと呼ばれます。
それらを1つのノードに保存しようとするのは悪い考えです。なぜなら、ほとんど静的なデータ(アイテムのプロパティ)と非常に揮発性の高いデータ(ジオロケーション情報)を混合しているからです。 2つを分離するとパフォーマンスが向上するため、Geofireはそれを実施します。
プロパティと地理データが同等に動的/静的であるユースケースが存在する場合がありますが、GeoFireは地理データと他のプロパティを単一の場所に保持することをサポートしていません。
同じ質問でこの投稿に最近アクセスした人たちにとって、これは Geofirestore ライブラリで可能です。これは、Firebase Firestoreデータベースの上に構築されたアプリのGeofireをサポートします。
新しいエントリごとにFirebase関数を使用して入力できます
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);
});
}
}