2015-06-09 24 views
14

Mam problem z pobraniem listy z bazy Firebase. Nie mam problemów z przechowywaniem, ale jak tylko próbuję rzucić dataSnapshot.getValue ArrayList(), aby moje awarii aplikacji, dając wyjątek:Jak odzyskać obiekt listy z bazy ogniowej w systemie Android

HashMap nie można rzutować na ArrayList

Ale kiedy próbowałem rzucić go do HashMap, ale także awarie, dając wyjątek:

ArrayList nie można rzutować na HashMap

Potrzebujesz pomocy! Oto kod, który tworzy problem:

Fire.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     List<TaskDes> td = (ArrayList<TaskDes>) dataSnapshot.getValue() 
     notifyDataSetChanged(); 
    } 

    @Override 
    public void onCancelled(FirebaseError firebaseError) { 

    } 
}); 

firebase object screen shot

Chcę odzyskać wszystkie dane w Firebase jako jedna lista. W TaskDes klasa zawiera trzy pola:

class TaskDes { // definition 
    boolean done 
    String taskDescription 
    String taskTitle 
} 
+0

Niestety nie ma wystarczająco dużo kod tutaj mi pomóc rozwiązywać problemy. Z pozytywnej strony: przykładowa aplikacja AndroidChat z Firebase robi wszystko, czego szukasz i niewiele więcej. Zajrzyj tutaj: https://github.com/firebase/AndroidChat/tree/master/app/src/main/java/com/firebase/androidchat. Niedawno wyjaśniłem trochę o jego wewnętrznych cechach w Grupie dyskusyjnej Google: https://groups.google.com/d/msg/firebase-talk/OCoQPvpgl1U/Nli_OywG7LYJ –

+0

Dzięki temu spróbuję, kolejna rzecz, o którą chcę zapytać jeśli przechowuję hashmap na bazie ogniowej, to podczas pobierania go z firebase mogę bezpośrednio rzucić datasnapshot.getValue() na hashmap ?? –

+0

Tak, to jest możliwe. Ale tylko wtedy, gdy poprawnie modelujesz klasę 'Task'. Spójrz na przykład. Twoje 'Zadanie' powinno wyglądać jak https://github.com/firebase/AndroidChat/blob/master/app/src/main/java/com/firebase/androidchat/Chat.java –

Odpowiedz

25

Trzeba utworzyć obiekt GenericTypeIndicator uchodzić za DataSnapshot.getValue() parametru.

Kod:

GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {}; 

List<String> yourStringArray = dataSnapshot.getValue(t); 
+9

Co się stanie, jeśli lista znajduje się wewnątrz innego obiektu? –

+0

@GregEnnis Czy wiesz, jak go rozwiązać, jeśli lista znajduje się wewnątrz innego obiektu? – malhobayyeb

+0

@malhobayyeb nope nigdy nie znalazłem dobrego sposobu na zrobienie tego –

6

danego modelu

public class TaskDes { 
    private boolean done; 
    private String taskDescription; 
    private String taskTitle; 

    public TaskDes() { 
    } 

    public boolean isDone() { 
     return done; 
    } 

    public void setDone(boolean done) { 
     this.done = done; 
    } 

    public String getTaskDescription() { 
     return taskDescription; 
    } 

    public void setTaskDescription(String taskDescription) { 
     this.taskDescription = taskDescription; 
    } 

    public String getTaskTitle() { 
     return taskTitle; 
    } 

    public void setTaskTitle(String taskTitle) { 
     this.taskTitle = taskTitle; 
    } 

} 

Trzeba stworzyć GenericTypeIndicator obiekt uchodzić za DataSnapshot.getValue() parametru.

W działalności

private static final String TAG=MainActivity.class.getSimpleName(); 
private FirebaseDatabase database; 
private DatabaseReference myRef=null; 

@Override 
protected void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    database=FirebaseDatabase.getInstance(); 
    myRef=database.getReference("ADD_YOUR_REFERECE"); 


    myRef.addValueEventListener(new ValueEventListener(){ 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot){ 
      /* This method is called once with the initial value and again whenever data at this location is updated.*/ 
      long value=dataSnapshot.getChildrenCount(); 
      Log.d(TAG,"no of children: "+value); 

      GenericTypeIndicator<List<TaskDes>> genericTypeIndicator =new GenericTypeIndicator<List<TaskDes>>(){}; 

      List<TaskDes> taskDesList=dataSnapshot.getValue(genericTypeIndicator); 

      for(int i=0;i<taskDesList.size();i++){ 
      Toast.makeText(MainActivity.this,"TaskTitle = "+taskDesList.get(i).getTaskTitle(),Toast.LENGTH_LONG).show(); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError error){ 
      // Failed to read value 
      Log.w(TAG,"Failed to read value.",error.toException()); 
     } 
    }); 
} 
0

Trochę późno, ale w przypadku któregokolwiek innego potrzebuje.

JEŻELI lista znajduje się wewnątrz innego obiektu.

Przedmiotem

public class Question { 

    public Date date; 
    public String questionNumber; 
    public String questionText; 
    public QuestionType questionType; 
    public String multipleSelection1; 
    public String multipleSelection2; 
    public String multipleSelection3; 

    public Question() { 
     // Default constructor required for calls to DataSnapshot.getValue(User.class) 
    } 
} 

Następnie, aby uzyskać szereg kwestii obiektów

GenericTypeIndicator<List<Question>> t = new GenericTypeIndicator<List<Question>>() {}; 
List<Question> questionList = dataSnapshot.getValue(t); 
0

dokonać innego elementu, który zawiera listę na swojej pozycji: jest to Twoja pozycja:

class TaskDes { // definition 
    boolean done 
    String taskDescription 
    String taskTitle 
} 

Jest to pozycja z listy

 class TaskDesList { // definition 
       private ArreyList<TaskDes> yourlist 
      } 

     public TaskDesList(){ 
     } 

     public ArrayList<TaskDes> getYourlist() { 
      return yourlist; 
     } 

i kiedy wywołanie EventListener

ref.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       yourlist.clear(); 
      taskDesList=dataSnapshot.getValue(TaskDesList.class); 
       if (taskDesList!=null) { 
        yourlist= taskDesList.getYourlist(); 
       } 
} 

i teraz „yourlist” to lista, która zawiera wszystkie swoje „TaskDes” pozycji