首先,您用于应用程序的结构是错误的。
让我们用户的一个示例应用程序
当您使用Geofire,你有两个数据列表:
a list of user details for each user
a list of latitude and longitude coordinates for each user
您正在尝试无论是在相同的结构存储这样
"users" : {
<userId> : {
"userData" : "userData",
<geofireData>
...
}
}
尝试将用户数据和geofiredata存储在一个节点中是一个糟糕的主意,因为您主要将静态数据(用户的属性)与高度易变的数据(地理位置i信息)。分离两个出来的导致更好的表现,这就是Geofire执行它的原因。
这就是为什么当您尝试将地理位置数据添加到用户节点时,它会覆盖该节点的先前用户详细信息。
你的数据库结构应该是这样的。
"Users" : {
<UserId> : {
"UserData" : "UserData",
...
}
}
"Users_location" : {
<UserId> : {
<geofireData> ...
}
}
因此,对于相同的用户ID创建2个结构,一个用于用户的详细信息,另一个用于用户的地理位置信息。
如何推送用户并设置geofire数据。
String userId = ref.child("users").push().getKey();
ref.child("users").child(userId).setValue(user);
geoFire = new GeoFire(ref.child("user_location"));
geoFire.setLocation(userId, new GeoLocation(lattitude, longitude));
您在地理定位中使用的userId与您在push()期间获得的相同。
因此,对于每个userId,您在anotehr结构中具有一个结构和位置细节的userdetails。
要获取数据,首先需要在users_location节点上执行GeoQuery,然后在onKeyEntered方法上获取数据。我的例子中的参数键是userId。
geoFire=newGeoFire(FirebaseDatabase.getInstance().getReference().child("users_location");
geoQuery = geoFire.queryAtLocation(geoLocation), radius);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
//retrieve data
//use this key which is userId to fetch user details from user details structure
}
};
编码愉快:)
我不会去反对由创建两个Geofire的,其对基于数据库火力地堡的人提出的建议。当用于多个密钥时,额外的呼叫不会导致太多开销。请参阅http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786。 –