2016-12-31 37 views
2

我已經創建了一個geofire firebase位置類。我能夠從位置表讀取訂戶鍵。但是,現在我想查詢訂戶表以獲得完整的訂戶對象。android中的二級回調不適用於嵌套查詢

內部方法onGeoQueryReady,我有所有的訂戶鍵。但是當我在onGeoQueryReady方法內部調用訂閱表時,它什麼都不返回。

public void findNearBySubscribers(final LocationInterface locationInterface, double radius, double clatitude, double clongitude){ 
     DatabaseReference ref = FirebaseDatabase.getInstance().getReference("location/"); 
     GeoFire geoFire = new GeoFire(ref); 
     final ArrayList<String> keys = new ArrayList<String>(); 
     GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(clatitude, clongitude), radius); 
     geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { 
      @Override 
      public void onKeyEntered(String key, GeoLocation location) { 
       keys.add(key); 
      } 

      @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) { 

      } 

      @Override 
      public void onGeoQueryReady() { 

       locationInterface.getNearBySubscribersCallback(keys); 
      } 

      @Override 
      public void onGeoQueryError(DatabaseError error) { 
       System.err.println("There was an error with this query: " + error); 
      } 
     }); 
    } 

下面的代碼根據鍵找到訂閱者不起作用。訂戶列表大小爲零,但響應字符串具有值。有人可以幫助我解決這個問題。看起來像這是一個2級的回調...

public void findNearBySubscribers(final LocationInterface locationInterface, double radius, double clatitude, double clongitude){ 
     DatabaseReference ref = FirebaseDatabase.getInstance().getReference("location/"); 
     GeoFire geoFire = new GeoFire(ref); 
     final ArrayList<String> keys = new ArrayList<String>(); 
     GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(clatitude, clongitude), radius); 
     geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { 
      @Override 
      public void onKeyEntered(String key, GeoLocation location) { 
       keys.add(key); 
      } 

      @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) { 

      } 

      @Override 
      public void onGeoQueryReady() { 
       final ArrayList<Subscriber> subscriberList = new ArrayList<Subscriber>(); 

       for(String key: keys) { 
        String url = "https://moe-90cc7.firebaseio.com/subscriber/"; 
        String uri = url + key + ".json"; 
        RestClient.get(uri, null, new TextHttpResponseHandler() { 
         @Override 
         public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
         } 

         @Override 
         public void onSuccess(int statusCode, Header[] headers, String responseString) { 
          Gson gson = new Gson(); 
          Subscriber subscriber = gson.fromJson(responseString, Subscriber.class); 
          System.out.println("Response Str" + responseString); 
          subscriberList.add(subscriber); 
         } 
        }); 
       } 
       System.out.println("List size "+subscriberList.size()); 
       locationInterface.getNearBySubscribersCallback(keys); 
      } 

      @Override 
      public void onGeoQueryError(DatabaseError error) { 
       System.err.println("There was an error with this query: " + error); 
      } 
     }); 
    } 

試圖紅丸的方式 - 但它不適合我。基本上我試圖在用戶密鑰可用時加載用戶。

package app.com.date.services; 

import com.firebase.geofire.GeoFire; 
import com.firebase.geofire.GeoLocation; 
import com.firebase.geofire.GeoQuery; 
import com.firebase.geofire.GeoQueryEventListener; 
import com.google.firebase.database.DatabaseError; 
import com.google.firebase.database.DatabaseReference; 
import com.google.firebase.database.FirebaseDatabase; 
import com.google.gson.Gson; 
import com.loopj.android.http.TextHttpResponseHandler; 

import java.util.ArrayList; 
import java.util.concurrent.Semaphore; 

import app.com.date.subscriber.Subscriber; 
import cz.msebera.android.httpclient.Header; 

public class LocationService { 
    private ArrayList<Subscriber> subscriberList = new ArrayList<Subscriber>(); 

    public void addGeoLocation(final LocationInterface locationInterface, String subscriberId, double latitude, double longitude) { 

     DatabaseReference ref = FirebaseDatabase.getInstance().getReference("location/"); 
     GeoFire geoFire = new GeoFire(ref); 
     geoFire.setLocation(subscriberId, new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() { 
      @Override 
      public void onComplete(String key, DatabaseError error) { 
       if (key != null) { 
        locationInterface.addLocationCallback(true); 
       } else { 
        locationInterface.addLocationCallback(false); 
       } 
      } 
     }); 
    } 

    public void findNearBySubscribers(final LocationInterface locationInterface, double radius, double clatitude, double clongitude) { 
     DatabaseReference ref = FirebaseDatabase.getInstance().getReference("location/"); 
     GeoFire geoFire = new GeoFire(ref); 
     final ArrayList<String> keys = new ArrayList<String>(); 
     final ArrayList<Subscriber> subscriberList = new ArrayList<Subscriber>(); 
     GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(clatitude, clongitude), radius); 
     geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { 
      @Override 
      public void onKeyEntered(String key, GeoLocation location) { 
       String url = "https://moe-90cc7.firebaseio.com/subscriber/"; 
       String uri = url + key + ".json"; 
       RestClient.get(uri, null, new TextHttpResponseHandler() { 
        @Override 
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
        } 
        @Override 
        public void onSuccess(int statusCode, Header[] headers, String responseString) { 
         Gson gson = new Gson(); 
         Subscriber subscriber = gson.fromJson(responseString, Subscriber.class); 
         System.out.println("Response Str" + responseString); 
         subscriberList.add(subscriber); 
        } 
       }); 

       System.out.println("onKeyEntered list "+subscriberList.size()); 

      } 

      @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) { 

      } 

      @Override 
      public void onGeoQueryReady() { 
       System.out.println("onGeoQueryReady list "+subscriberList.size()); 
      } 

      @Override 
      public void onGeoQueryError(DatabaseError error) { 
       System.err.println("There was an error with this query: " + error); 
      } 
     }); 
    } 
} 

OUTPUT

12-31 17:57:34.090 13956-14019/app.com.date V/FA: Processing queued up service tasks: 3 
12-31 17:57:34.366 13956-13956/app.com.date I/System.out: onKeyEntered list 0 
12-31 17:57:34.366 13956-13956/app.com.date I/System.out: onKeyEntered list 0 
12-31 17:57:34.366 13956-13956/app.com.date I/System.out: onGeoQueryReady list 0 
12-31 17:57:34.456 13956-13956/app.com.date V/AsyncHttpRH: Progress 332 from 332 (100%) 
12-31 17:57:34.475 13956-13956/app.com.date I/System.out: Response Str{"age":29,"alcohol":false,"animalLover":false,"children":false,"id":"GYlSDXx0Kwh7AerOzFGf8MDmhOg1","isEmpty":false,"mainImage":"https://firebasestorage.googleapis.com/v0/b/moe-erOzFGf8MDmhOg1%2F1265290048?alt=media&token=80ab1410-bac9-4679-a3d4-152204319310","name":"singh","smoker":false} 
12-31 17:57:34.574 13956-13956/app.com.date V/AsyncHttpRH: Progress 327 from 327 (100%) 
12-31 17:57:34.584 13956-13956/app.com.date I/System.out: Response Str{"age":65,"alcohol":false,"animalLover":false,"children":false,"id":"xZWPMjWQCYY4xNimx3WHqVZcQxs1","isEmpty":false,"mainImage":"https://firebasestorage.googleapQCYY4xNimx3WHqVZcQxs1%2F1405868067?alt=media&token=b8d128a6-7156-42e8-9d0b-953feb128b4c","name":" Singh","smoker":false} 
12-31 17:57:39.123 13956-14019/app.com.date V/FA: Inactivity, disconnecting from the service 

回答

1

的問題是在這樣的代碼:

final ArrayList<Subscriber> subscriberList = new ArrayList<Subscriber>(); 

for(String key: keys) { 
    String url = "https://moe-90cc7.firebaseio.com/subscriber/"; 
    String uri = url + key + ".json"; 
    RestClient.get(uri, null, new TextHttpResponseHandler() { 
     @Override 
     public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
     } 

     @Override 
     public void onSuccess(int statusCode, Header[] headers, String responseString) { 
      Gson gson = new Gson(); 
      Subscriber subscriber = gson.fromJson(responseString, Subscriber.class); 
      System.out.println("Response Str" + responseString); 
      subscriberList.add(subscriber); 
     } 
    }); 
} 
System.out.println("List size "+subscriberList.size()); 
locationInterface.getNearBySubscribersCallback(keys); 

的數據從裝載火力地堡異步。這意味着在您打印subscriberList.size()時,您尚未加載任何訂閱者。

這是最簡單的,看看你的代碼更改輸出一些簡單的日誌語句:

final ArrayList<Subscriber> subscriberList = new ArrayList<Subscriber>(); 

System.out.println("Before starting to load"); 
for(String key: keys) { 
    String url = "https://moe-90cc7.firebaseio.com/subscriber/"; 
    String uri = url + key + ".json"; 
    RestClient.get(uri, null, new TextHttpResponseHandler() { 
     @Override 
     public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
     } 

     @Override 
     public void onSuccess(int statusCode, Header[] headers, String responseString) { 
      Gson gson = new Gson(); 
      Subscriber subscriber = gson.fromJson(responseString, Subscriber.class); 
      System.out.println("Response Str" + responseString); 
      subscriberList.add(subscriber); 
      System.out.println("In onSuccess, list size "+subscriberList.size()); 
     } 
    }); 
} 
System.out.println("After starting to load, list size "+subscriberList.size()); 
locationInterface.getNearBySubscribersCallback(keys); 

這樣做的結果應該是:

開始加載

之後之前開始加載,列表大小0

在onSuccess中,列表大小1

在的onSuccess,列表大小2

...

所以,你可以看到在onSuccess()運行的代碼後的代碼下的文件中。請記住:這是因爲數據是異步加載的,在處理現代Web /雲API時是完全正常的行爲。

解決方案是重構您的問題。不要說「首先加載用戶,然後與他們一起做xyz」,嘗試將問題重新定義爲「每當用戶改變時,與他們一起做xyz」。

執行這是您移動,做的東西給用戶代碼爲onSuccess處理程序,就像我和打印用戶列表的長度來完成。

+0

感謝您的回覆,問題是我從其他活動調用此方法,我需要在該活動中可用的訂戶列表來填充列表視圖。 – user7327850

+0

所以我不能在onsucces方法中做任何事情,我想要回調來返回訂閱者列表。 – user7327850

+0

你不能返回尚未加載的東西。你不能讓方法等待Android(也不應該)。請參閱http://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener。但是,如果重新構建問題,則可以「開始加載用戶列表,然後在加載用戶時填充列表視圖」。 –