2017-04-23 1 views
1

firebase 데이터베이스에서 아이템 목록을 얻으려고합니다 ... 그러나 그것을 얻는데 문제가 있습니다. 내 코드는 더 많거나 적은 같은 같습니다firebase에서 데이터 쿼리하기

List<Items> itemsList; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_work_items_report); 

    itemsList = GetItems(); 
} 

내 항목을 반환하는 메소드는 다음과 같습니다 항상)

private ArrayList<Items> GetItems(){ 
    DatabaseReference database = FirebaseDatabase.getInstance().getReference(); 
    DatabaseReference ref = database.child("items"); 
    final ArrayList<Items> itemsRez = new ArrayList<Items>(); 
    Query itemsQuery = ref.orderByChild("type"); 

    itemsQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      if (dataSnapshot.exists()) { 
       for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) { 
        Items item = singleSnapshot.getValue(Items.class); 
        itemsRez.add(item); 
       } 
      } 
     } 
     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
    return itemsRez; 
} 

GetItems (나에게 좀 의미가 널리스트를 반환 ,이 목록을 반환하기 전에 onDataChange 이벤트를 발생시키는 것이 없으므로 내 질문은 ... 어떻게이 메서드를 사용하여 DB에서 항목 목록을 반환 할 수 있습니까?

+0

onDataChange 내부 데이터를 사용하여 뭐가 문제? 스레드를 차단하는 것은 나쁜 생각입니다. – Selvin

+0

맞아, 나는 onDataChange에서 그것을하는 것이 더 낫다고 생각한다. 하지만 여전히 내가하는 일이 최선의 아이디어가 아니더라도 어떻게 할 수 있습니까? –

+0

itemsList를 사용중인 코드를 onDataChange로 이동하십시오. – Selvin

답변

3

addListenerForSingleValueEvent()으로 전화를 걸면 Firebase 클라이언트 은 서버에서 데이터를로드하기 시작합니다.에는 시간이 걸릴 수 있습니다. 응용 프로그램이 응답하지 않도록 응용 프로그램이 응답하지 않도록 차단하는 응용 프로그램을 차단하기 위해 별도의 스레드에 데이터를로드합니다. 따라서 데이터가로드되는 동안 주 스레드가 계속 실행되어 현재 상태 인 itemsRez을 반환하며 이는 빈 목록입니다.

그것은 당신이 당신의 코드에 몇 로깅 문을 추가하는 경우이를보고 가장 쉬운 방법 : 첨부

:

private ArrayList<Items> GetItems(){ 
    DatabaseReference database = FirebaseDatabase.getInstance().getReference(); 
    DatabaseReference ref = database.child("items"); 
    final ArrayList<Items> itemsRez = new ArrayList<Items>(); 
    Query itemsQuery = ref.orderByChild("type"); 

    System.out.println("Attaching listener"); 
    itemsQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      if (dataSnapshot.exists()) { 
       for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) { 
        Items item = singleSnapshot.getValue(Items.class); 
        itemsRez.add(item); 
       } 
      } 
      System.out.println("Received "+itemsRez.size()+" items"); 
     } 
     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
    System.out.println("Returning "+itemsRez.size()+" items"); 
    return itemsRez; 
} 

당신은 가능성이 기대하는 것과는 달리, 이것은 순서로 로그를 출력합니다 청취자

반환 0 항목

받은 항목

문제의 일반적인 해결책 중 하나는 코드의 목표를 다시 짜는 것입니다. "먼저 항목을 가져온 다음 abc를 사용하여"코드를 "항목을 가져 오기 시작한 다음, 들어올 때 abc를 사용하여"작성하십시오. 코드에서는 itemsRec코드가onDataChange 메서드로 이동한다는 것을 의미합니다.이 메서드는 적절한 순간에 호출됩니다. 즉, 항목이로드되었을 때입니다.

또한 참조 :

관련 문제