2016-09-27 19 views
5

Jestem nowy w Firebase i NoSQL. Mam demo Androida z polem autouzupełniania City City, w którym podczas wpisywania tekstu chcę zapełniać moje miasta z bazy danych Firebase DB.Pobieranie danych z bazy danych Firebase Realtime w systemie Android

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

To jest to, co do tej pory miałem.

Jak mogę pobrać z miast DB, które zaczynają się od litery (dane wejściowe z klawiatury)? Jeśli zacznę pisać "G", chcę otrzymać "Guayaquil" i "Gualaceo".

Jeśli użyję orderByValue zawsze zwróci pustą migawkę.

Jeśli użyję orderByKey zwrócę całą listę.

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()); 
      } 

Uwaga: Jeśli możesz polecić lepszą strukturę danych, jesteś mile widziany.

+0

Jak duży będzie to baza miast być? Czy aplikacja mogłaby raz odczytać w bazie danych lokalną kopię (taką jak tablica), a następnie użyć lokalnej logiki, aby wyświetlać tylko odpowiednie wartości podczas pisania? – Ryan

+0

Początkowo będzie to około 10, ale może wzrosnąć nawet do 100. Chciałem, aby ta funkcja była "online", dzięki czemu mogę dodawać nowe miasta bez potrzeby przechowywania ich lokalnie. –

+0

To dobrze. Jeśli chodzi o procesor i sieć, to 100 małych strun to właściwie nic, więc zdecydowanie będzie szybko. Pozwól mi wyjaśnić, co mam na myśli, przechowując je lokalnie. Mam na myśli pamięć podczas uruchamiania, to wszystko. Nie chodzi mi o przechowywanie kopii w pamięci urządzeń ani niczego w tym stylu. Chodzi o to, że czytam miasta w tablicy, a następnie pracuję z tą tablicą, aby wyświetlić dane. Gdy baza danych się zmienia, możesz bardzo łatwo zaktualizować tablicę niemal natychmiast, ale wątpię, by zmieniała się ona często. Sprawdź moją odpowiedź, aby dowiedzieć się więcej o tym, co myślałem. – Ryan

Odpowiedz

6

@NicholasChen zidentyfikował problem. Ale oto sposób, w jaki zaimplementujesz użycie 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()); 
     } 

zaczynając od danych wprowadzonych przez użytkownika, a kończąc na ostatnim ciąg, który zaczyna się na danych wprowadzonych przez użytkownika, można uzyskać wszystkie pasujące przedmioty

Na stosunkowo krótkich listach przedmiotów podejście Ryana będzie również działać dobrze . Jednak powyższe zapytanie Firebase będzie filtrować po stronie serwera.

Aktualizacja

Właśnie prowadził ten kod:

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

     } 
    }); 

I drukowane:

prawdziwą

prawdziwą

Więc Clea rly pasuje do dwóch miast.

Zapraszam do testowania przeciwko mojej bazy danych: https://stackoverflow.firebaseio.com/39714936

+0

Powraca pusta migawka –

+0

Przetestowałem i działa dla mnie. Dodałem do pytania pełny opis i link do mojej bazy danych. –

+0

Testowałem również i działa idealnie –

0

Oczywiście OrderByValue nic nie zwraca, ponieważ to jest boolean, który masz.

możesz użyć metod startAt i endAt, aby to zrobić. (Poniższy kod jest Firebase 2,0 za)

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()); 
}); 

Można badać więcej na Firebase 3 Dokumentacja miejscu here.

To, co zrobił Ryan, było słuszne. Musisz jednak uruchomić startAt na DataSnapshot, aby upewnić się, że twoje "aktywne" wyszukiwanie działa.

+0

kod jest potrzebny do aplikacji na Androida –

+0

. Dlaczego jest to oznaczone w Androidzie? – Nicholas

+0

Nie sądzę, że używasz startAt z moją metodą, ponieważ wykonuję kwerendę, przypisuję odbiornik w czasie rzeczywistym, aby nasłuchiwał wszelkich zmian w bazie danych. – Ryan

1

Spróbuj czegoś takiego, aby powtórzyć migrację dzieci w migawce cities i dodać wszystkie miasta do ArrayList z Strings.

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()); 
     // ... 
    } 
}); 

Edycja niniejszym punkcie dla jasności:

Pozwoli to uzyskać wszystkie miasta wczytywane do pamięci programu, dzięki czemu można wykorzystać te dane do wyświetlenia miast do użytkownika. Jeśli lista miast ulegnie zmianie, będą również widoczne dane użytkownika. Jeśli użytkownik nie jest online, to nie zadziała. To umieszcza w bazie danych w czasie rzeczywistym tylko słuchacza online.

Logika w głowie jest coś takiego:

  1. ustawić wartość słuchacza w polu tekstowym.
  2. Po wpisaniu typów użytkownika, utwórz widok, aby wyświetlić wszystkie elementy z listy tablic , które rozpoczynają się od tego samego podciąganego napisu.
  3. Oczywiście błędy arrayIndex.

Mam nadzieję, że to pozwoli ci na dobrej drodze. Jestem pewien, że istnieją inne sposoby, w jakie można go wdrożyć, ale osobiście to robię. Jeśli potrzebujesz pomocy z kodem, aby wyświetlić właściwe miasta, rozpocznij ze mną czat i mogę przeprowadzić z Tobą burzę mózgów.

+0

Rozumiem twój punkt widzenia, ale chciałem zachować tę funkcję "autouzupełniania" w Internecie, aby móc dodawać lub usuwać miasta, bez konieczności lokalnego przechowywania. –

+1

Nadal będzie on w Internecie tak, jak ja to robię. Bez względu na to, co zrobisz, będziesz musiał w pewnym momencie odczytać dane do zmiennej lub Twoja aplikacja nie będzie mogła wyświetlić nazwy miasta. Wciąż obsługuje on usuwanie online, a jeśli ktoś usunie miasto, podczas pisania którego inny użytkownik będzie nadal aktualizował listę innych użytkowników podczas pisania. Myślę, że mógłbym wyjaśnić źle słuchacza, a może po prostu nie rozumiem wymagań. – Ryan

+0

Zgaduję, że twoje podejście jest poprawne. Ale moim pomysłem było wysłanie Firebase pierwszych liter miasta, aw Migawce, wyszczególnienie tylko miast, które zaczynają się tymi literami. –

Powiązane problemy