【发布时间】:2017-02-10 18:24:09
【问题描述】:
我有这个搜索功能,可以使用 GeoFire 使用 Firebase 数据库搜索特定用户。
我想做什么:
在GeoQueryEventListener() 和onKeyEntered 中,我想将找到的每个键添加到一个ArrayList(onKeyEntered() 之外)。
我遇到的问题:
当我在onKeyEntered() 中打印它时,它可以工作。
但是一旦我退出GeoQueryEventListener(),keysGeolocated 就是空的
public ArrayList<User> search(GeoFire geoFire, int day, final boolean isBartender, double latitude, double longitude, double radius, double rate, double nightlyRate, double hourlyRate, final String speciality){
keysGeolocated = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
root = database.getReference();
DatabaseReference usersRef = root.child("Users");
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), radius);
geoQuery.addGeoQueryEventListener(new MyGeoListener(keysGeolocated));
System.out.println("KEYS GEOLOCATED" + keysGeolocated);
final ArrayList<User> result = new ArrayList<>();
for(String key : keysGeolocated){
Query queryByLocation = usersRef.orderByKey().equalTo(key);
DatabaseReference refToLocationQuery = queryByLocation.getRef();
if(checkRefNull(refToLocationQuery) == true) {
System.out.println("QUERY BY LOCATION NULL");
continue;
}
Query queryByTypeOfUser = refToLocationQuery.orderByChild("isBarTender").equalTo(isBartender);
DatabaseReference refToTypeOfUserQuery = queryByTypeOfUser.getRef();
if(checkRefNull(refToTypeOfUserQuery) == true) {
System.out.println("QUERY BY TYPE NULL");
continue;
}
Query queryByRate = refToTypeOfUserQuery.orderByChild("rate").startAt(rate);
DatabaseReference refToRateQuery = queryByRate.getRef();
if(checkRefNull(refToRateQuery) == true) {
System.out.println("QUERY BY RATE NULL");
continue;
}
DatabaseReference finalRef = null;
if(isBartender == true){
if(nightlyRate == 0){
Query queryByPrice = refToRateQuery.orderByChild("nightlyRate").endAt(nightlyRate);
finalRef = queryByPrice.getRef();
}
else if(hourlyRate == 0){
Query queryByPrice = refToRateQuery.orderByChild("hourlyRate").endAt(hourlyRate);
finalRef = queryByPrice.getRef();
}
//TODO Impelement checks for available dates
}
else{
finalRef = refToRateQuery;
}
finalRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getValue()!=null){
User userFound = dataSnapshot.getValue(User.class);
if(isBartender == true){
Bartender barTenderFound = (Bartender) userFound;
if(speciality != null){
if(barTenderFound.getSpeciality().contains(speciality)){
result.add(barTenderFound);
}
}
else{
result.add(barTenderFound);
}
}
else{
result.add(userFound);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
return result;
}
public boolean checkRefNull(DatabaseReference ref){
final boolean[] result = new boolean[1];
result[0] = false;
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("TEST1");
if(dataSnapshot.getValue()==null){
result[0] = true;
System.out.println("TESTTEST");
}
else{
System.out.println("TESTTEST TRUE" + dataSnapshot.getValue());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return result[0];
}
public void setBarTender(boolean barTender){
this.barTender = barTender;
}
}
class MyGeoListener implements GeoQueryEventListener {
private ArrayList<String> keysGeolocated;
MyGeoListener(ArrayList<String> keysGeolocated){
this.keysGeolocated = keysGeolocated;
}
@Override
public void onKeyEntered(String key, GeoLocation location) {
keysGeolocated.add(key);
}
@Override
public void onKeyExited(String key) {
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
}
@Override
public void onGeoQueryReady() {
}
@Override
public void onGeoQueryError(DatabaseError error) {
}
}
【问题讨论】:
-
更改范围。不能是该方法的本地。
-
您假设来自侦听器的即时结果。如果它是同步的,您的调用将打印该列表。不幸的是,这个监听器是异步的。当事件触发时,它将在列表中添加数据。过了一段时间,您才能看到打印的作品。
-
必须是匿名类吗? :-}
标签: java android firebase inner-classes geofire