Android Firebase位置查询
我正在用firebase在android上设计一个基于位置的餐馆搜索应用程序。firebase上的餐厅等级如下:Android Firebase位置查询,android,firebase,location,firebase-realtime-database,Android,Firebase,Location,Firebase Realtime Database,我正在用firebase在android上设计一个基于位置的餐馆搜索应用程序。firebase上的餐厅等级如下: restaurants -key address: "NYC" city: "New York" description: "" id: 60000 latitude: 39.895107 longitude: 32.797819 name: "Pizza Store" 片段类 mainActivity.mDatabase.child("restaur
restaurants
-key
address: "NYC"
city: "New York"
description: ""
id: 60000
latitude: 39.895107
longitude: 32.797819
name: "Pizza Store"
片段类
mainActivity.mDatabase.child("restaurants").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println("There are " + snapshot.getChildrenCount() + " restaurans");
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Restaurant post = postSnapshot.getValue(Restaurant.class);
mapmap2.put(post.getName(), postSnapshot.getKey());
restaurants.add(post);
}
adapter = new RestaurantCardViewAdapter(getActivity(), restaurants, MapListFragment.this);
mRecyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
现在,我可以列出所有的餐馆。但我想查询用户位置。首先,我想列出用户位置附近的20家餐馆,当用户加载页面时,我想得到接下来的20家最近的餐馆。我在网上搜索。我找到了GeoFire库,但据我所知,它与firebase的遗留版本一起工作。如何使用这些标准进行查询?Firebase查询只能按单个属性进行筛选/排序。由于位置由经度和纬度组成,因此按照您现在的格式,无法基于位置进行查询 幸运的是,有一个名为的附加库。此库将经度和纬度合并为一个名为的属性。基于此特性,它可以根据到给定位置的距离进行过滤
我建议您查看Geofire,看看它是否适合您的用例。我在答案的帮助下解决了这个问题。我为geofire推了一个名为“餐厅位置”的单独孩子。当我插入餐厅时,我会分别推送位置
GeoFire geoFire;
String itemId = mDatabase.child("restaurants").push().getKey();
mDatabase.child("restaurants").child(itemId).setValue(restaurant);
geoFire = new GeoFire(mDatabase.child("restaurants_location"));
geoFire.setLocation(itemId, new GeoLocation(Double.valueOf(rd.location.latitude), Double.valueOf(rd.location.longitude)));
然后,当我需要查询位置时,我使用geofire查询
geoFire = new GeoFire(mDatabase.child("restaurants_location"));
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(39.896263, 32.799652), 1);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
System.out.println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude));
mDatabase.child("restaurants").child(key).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
Restaurant res= snapshot.getValue(Restaurant.class);
}
@Override
public void onCancelled(DatabaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
// ...
});
}
@Override
public void onKeyExited(String key) {
System.out.println(String.format("Key %s is no longer in the search area", key));
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
System.out.println(String.format("Key %s moved within the search area to [%f,%f]", key, location.latitude, location.longitude));
}
@Override
public void onGeoQueryReady() {
System.out.println("All initial data has been loaded and events have been fired!");
}
@Override
public void onGeoQueryError(DatabaseError error) {
System.err.println("There was an error with this query: " + error);
}
});
但我仍然担心这是否是从数据库中获取餐馆的最有效方法,因为我在“餐馆”根上分别为每个餐馆键运行查询。有没有人知道更有效的方法请告诉我们。谢谢您的回答。我搜索GeoFire的属性。但我有一些疑问。建议将位置条目与餐厅分开。输入带有餐厅ID的位置信息,并查询该位置根。就像在这个链接中一样。但我不明白,当我查询位置时,我会得到最近的餐厅钥匙。在那之后,我必须用这些钥匙去餐馆。我怎么能做到这一点,这不是一个昂贵的数据库吗?事实上不是。由于使用GeoHash,GeoFire通常需要读取比返回更多的位置数据。通过让您单独查找附加信息,您实际上可能会使用更少的带宽。而且它并不像你想象的那么慢,因为Firebase通过现有的连接管道传输请求。看,是的,如果能得到一个答案会很有趣,这是最有效的方法。弗兰克·范·帕夫伦……谢谢^^