19

アプリを開発して、、、などの文字列を Firebase データベースに保存してpostedAtTimepostedByますpostedOnDate。上記のすべての文字列が保存されているのと同じノードに 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);
}

データベースに保存される方法は次のとおりです。

データベース構造のスクリーンショット

私が望むのは、-KLIoLUsI0SpQZGpV1h4ここにある同じノードに GeoFire 座標を保存することです。これは単なるプッシュ ID であり、ランダムに生成されます。

私はこの参照を与えることによってそれを試しました:

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

そして、上記のように他のアイテムでそれを押します。ただし、これは GeoFire 座標のみを保存し、ノードの下の他のアイテムは保存しませんでしたrequests

では、同じノード内のすべてのデータと一緒に保存されるようにするには、GeoFire 参照はどうすればよいでしょうか?

ここで何がうまくいかないのですか?私にお知らせください。

4

4 に答える 4

39

フランクの答えは正しいですが、例を挙げたいと思います。データベース構造は次のようになります。

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

items_locationデータを取得するには、まずノードでGeoQuery を実行し、次にonKeyEnteredメソッドでデータを取得する必要があります。パラメータkeyitemId私の例からのものです。

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呼び出しで保存します

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);
于 2016-07-13T06:53:00.277 に答える
13

Geofire を使用すると、次の 2 つのデータ リストがあります。

  1. 通常のプロパティを持つアイテムのリスト
  2. Geofire を介してクエリを実行する geohash インデックスとそれに関連付けられたキーのリスト

キーを使用して、Geoquery の結果から通常のアイテムを取得します。そのため、Geofire のイベントは「Key Entered」、「Key Exited」などと呼ばれます。

ほとんどの静的データ (アイテムのプロパティ) と非常に揮発性の高いデータ (地理的位置情報) を混在させているため、それらを 1 つのノードに格納しようとするのはお勧めできません。2 つを分離すると、パフォーマンスが向上します。これが、Geofire が強制する理由です。

プロパティと地理データが同等に動的/静的であるユースケースが存在する可能性がありますが、GeoFire は地理データとその他のプロパティを 1 つの場所に保持することをサポートしていません。

于 2016-07-13T01:09:22.267 に答える