2016-09-27 222 views
5

我是Firebase和NoSQL的新手。我有一個Android演示,其中有一個城市自動填充文本字段,我想在輸入時填充Firebase數據庫中的城市。從Android中的Firebase實時數據庫檢索數據

{ "cities":{ 
     "Guayaquil":true, 
     "Gualaceo":true, 
     "Quito":true, 
     "Quevedo":true, 
     "Cuenca":true, 
     "Loja":true, 
     "Ibarra":true, 
     "Manta":true 
    } 
} 

這是我到目前爲止。

如何從數據庫中以字母(鍵盤輸入)開頭的城市檢索?如果我開始輸入「G」,我想收到「瓜亞基爾」和「Gualaceo」。

如果我使用orderByValue總是返回一個空的快照。

如果我用orderByKey返回整個列表。

Query citiesQuery = databaseRef.child("cities").startAt(input).orderByValue(); 
    citiesQuery.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      List<String> cities = new ArrayList<String>(); 
      for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { 
       cities.add(postSnapshot.getValue().toString()); 
      } 

注:如果你能推薦一個更好的數據結構,歡迎您。

+0

多大將城市這個數據庫是什麼?您的應用程序是否可以將數據庫中的數據讀入本地副本(如某種數組),然後使用本地邏輯在打字時僅顯示適當的值? – Ryan

+0

最初它將在10左右,但可以增加到100.我希望這個功能是「在線」的,所以我可以添加新的城市,而不需要在本地存儲 –

+0

哦,這很好。就處理器和網絡而言,100個小字符串實際上什麼都不是,所以它肯定會很快。讓我通過本地存儲來澄清我的意思。我的意思是在運行時在內存中,這就是全部。我不是說要在設備存儲器或類似的東西中存儲一個副本。我的意思是,將城市讀入數組,然後使用該數組顯示數據。當數據庫發生變化時,您可以非常輕鬆地立即更新陣列,但我懷疑它會經常更改。查看我的答案,以獲得更多關於我在想什麼的解釋。 – Ryan

回答

6

@NicholasChen發現了這個問題。但這是你用3來實現的方式。X SDK:

DatabaseReference cities = databaseRef.child("cities") 
Query citiesQuery = cities.orderByKey().startAt(input).endAt(input+"\uf8ff"); 
citiesQuery.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     List<String> cities = new ArrayList<String>(); 
     for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { 
      cities.add(postSnapshot.getValue().toString()); 
     } 

通過啓動在用戶輸入並與用戶輸入開始最後一個字符串結尾,你得到所有符合條件的物品

對於項目的相對短名單瑞安的做法也將正常工作。但上面的Firebase查詢將過濾服務器端。

更新

我只是跑這個代碼:

DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("39714936"); 

    String input = "G"; 

    DatabaseReference cities = databaseRef.child("cities"); 
    Query citiesQuery = cities.orderByKey().startAt(input).endAt(input + "\uf8ff"); 
    citiesQuery.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      List<String> cities = new ArrayList<String>(); 

      for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { 
       cities.add(postSnapshot.getValue().toString()); 
      } 
      System.out.println(cities); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

而且它印:

真正

真正

所以CLEA rly匹配兩個城市。

隨意測試對我的數據庫:https://stackoverflow.firebaseio.com/39714936

+0

它正在返回一個空的快照 –

+0

我測試過,它適用於我。我添加了完整的片段和鏈接到我的數據庫的問題。 –

+0

我也測試過它,並且工作正常 –

0

當然,OrderByValue不會返回任何內容,因爲這是您擁有的布爾值。

您可以使用startAt和endAt方法來執行此操作。 (以下是火力地堡2.0的代號)

var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs"); 
ref.orderByKey().startAt("b").endAt("b\uf8ff").on("child_added", function(snapshot) { 
    console.log(snapshot.key()); 
}); 

您可以探索更多的火力地堡3文檔網站here

瑞安做的是對的。但是,您必須在dataSnapshot上實施startAt以確保您的「實時」搜索有效。

+0

該代碼是Android應用程序所需的 –

+0

這就是爲什麼這是在Android標籤? – Nicholas

+0

我不認爲你用我的方法startAt,因爲我正在執行一個查詢,我分配一個實時偵聽器來偵聽對數據庫的任何更改。 – Ryan

1

嘗試類似的方法來遍歷cities快照中的子項並將所有城市添加到StringsArrayList

ArrayList<String> cityList = new ArrayList<>(); 

databaseRef.child("cities").addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     cityList.clear(); 
     for (DataSnapshot data : dataSnapshot.getChildren()){ 
      cityList.add(data.getKey); 
     } 

    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 
     Log.w(TAG, "getUser:onCancelled", databaseError.toException()); 
     // ... 
    } 
}); 

編輯本段爲清楚:

這將讓你的所有城市讀入程序存儲器,所以你可以利用這些數據來顯示城市的用戶。如果城市列表發生變化,用戶看到的數據也會變化。如果用戶不在線,這將無法工作。這將在數​​據庫上放置一個實時的在線唯一監聽器。

邏輯在我心中是一樣的東西:

  1. 坐落在文本框中輸入值聽衆。
  2. 當用戶鍵入時,使視圖顯示數組列表 中的所有項目,這些項目以鍵入的相同子字符串開頭。
  3. 當然處理arrayIndex錯誤。

希望這會讓你走上正軌。我相信還有其他方法可以實施,但這是我個人的做法。如果您需要幫助顯示正確城市的代碼,請與我開始聊天,我可以與您一起集體討論。

+0

我明白了你的觀點,但我想保持「自動完成」功能在線,以便我可以添加或刪除城市,而無需在本地存儲。 –

+1

它仍然是我在做這件事的方式。不管你做什麼,你都必須在某個時間點將一些數據讀入變量,否則你的應用程序將無法顯示城市名稱。它仍然支持在線刪除,如果有人在另一個用戶正在輸入時刪除了一個城市,在輸入時仍然會更新其他用戶列表。我想我可能是在解釋聽衆的錯誤,或者我只是誤解了需求。 – Ryan

+0

我想你的方法是正確的。但是mi的想法是將Firebase發送給一個城市的第一個字母,並且在快照中,只列出以這些字母開頭的城市。 –

相關問題