2017-08-05 14 views
5

Uygulamamdaki her kullanıcı arkadaşlık istekleri gönderip alabilir. Kullanıcı arkadaşlarının isteklerini kontrol ettiğinde, uygulamanın kendisine bir arkadaşlık isteği gönderen her kullanıcı üzerinden gitmesini ve bilgilerini Realtime Database'dan almasını istiyorum. Ben bu kodu 2 ValueEventListeners sahipFirebase - Her bir kullanıcının verilerini bir listeye almaya çalışmak

public void check_For_Friends_And_Requests(){ 
     String loggedUser=SaveSharedPreference.getLoggedEmail(getApplicationContext()); 


      final DatabaseReference mDatabase= FirebaseDatabase.getInstance().getReference(); 
      final DatabaseReference userRef=mDatabase.child("Users").child(loggedUser); 

      userRef.addListenerForSingleValueEvent(new ValueEventListener() { 
       @Override 
       public void onDataChange(DataSnapshot dataSnapshot) { 
        if (dataSnapshot.exists()){ 

         final List<User> friendRequestsReceived_UserList=new ArrayList<>(); 

         for (DataSnapshot postSnapshot: dataSnapshot.child("friend_requests_received").getChildren()) { 

          final String senderEmail=postSnapshot.getKey(); 

          Toast.makeText(getApplicationContext(), 
            senderEmail, Toast.LENGTH_SHORT).show(); 

          if (senderEmail!=null){ 
           mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() { 
            @Override 
            public void onDataChange(DataSnapshot dataSnapshot) { 
             Toast.makeText(getApplicationContext(), 
               dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show(); 

             friendRequestsReceived_UserList.add(
               new User(
                 senderEmail, 
                 dataSnapshot.child("name").getValue(String.class), 
                 dataSnapshot.child("level").getValue(Integer.class), 
                 dataSnapshot.child("skill").getValue(Double.class))); 

            } 

            @Override 
            public void onCancelled(DatabaseError databaseError) { 

            } 
           }); 

          } 
         } 

         UserListAdapter friendRequestsReceived_Adapter = 
         new UserListAdapter(getApplicationContext(), 
           R.layout.friend_requests_received_listview_row, 
           friendRequestsReceived_UserList); 

         friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); 

        } 

        else 
        connectionErrorGoToMain(); 
       } 

       @Override 
       public void onCancelled(DatabaseError databaseError) { 
        connectionErrorGoToMain(); 
       } 
      }); 


    } 

:

Bu Bunu gerçekleştirmek için benim kodudur. İçerdeki kullanıcı bilgilerini listeye ekliyorum. Sorun, bu işlemin sonunda listenin boş olmasıdır.

Bu satırları kullanarak bu bilgileri içeren bir liste görünümü doldurmak istiyorum:

UserListAdapter friendRequestsReceived_Adapter = 
         new UserListAdapter(getApplicationContext(), 
           R.layout.friend_requests_received_listview_row, 
           friendRequestsReceived_UserList); 

         friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); 

Ben innner dinleyici Onları içine koyduğunuzda, iyi çalışıyor, ama adaptör ayarlamak istemiyorum Listedeki her kullanıcı için, yalnızca for döngüsünden sonra.

benim veritabanı yapısına sahip bir ekran görüntüsü (Ben tüm parametreleri almak gerekmez) takılarak ediyorum

: Eğer iç onDataChange() dışında friendRequestsReceived_UserList ilan çünkü

enter image description here

+0

Ben tüm yapabileceğiniz Sınıf kullanım { Liste friendReuqest = yeni gibi her nesne ile .... Mağaza Listesi Ben bir ekran görüntüsü –

+0

olduğunu görmek için sana ihtiyacım ArrayList(); Dize adı; } ve Ondata değişim İşleyici içinde friendReqest çocuk üzerinde iç içe sorgu yapmak ve model İlk olsun listesine SetValue sonra kendisine dataSnapshot geçmek ve ardından userlist dataSnapshot.getValue (Kullanıcı bunu sizin modelinde listesini eklemek ve saklayın. class), –

+0

ekledik @ILAYS_Kerbal sizin Firebase veri yapısı –

cevap

1

listesi boş yöntem. Bu, bu yeni nesneleri listeye eklemeden önce çağrılan onDataChange() yönteminin eşzamansız davranışı nedeniyle gerçekleşiyor. Yani, bu çözmek için, sadece bu gibi iç onDataChange() yöntemi içinde listenin beyanı taşıyın: Muhtemelen Gördüğünüz gibi

if (senderEmail!=null){ 
mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     final List<User> friendRequestsReceived_UserList=new ArrayList<>(); //Moved here 

    Toast.makeText(getApplicationContext(), dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show(); 

    friendRequestsReceived_UserList.add(
     new User(
      senderEmail, 
      dataSnapshot.child("name").getValue(String.class), 
       dataSnapshot.child("level").getValue(Integer.class), 
      dataSnapshot.child("skill").getValue(Double.class))); 
      UserListAdapter friendRequestsReceived_Adapter = 

    new UserListAdapter(getApplicationContext(), R.layout.friend_requests_received_listview_row, friendRequestsReceived_UserList); 
    friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter); 

    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 

    } 
}); 

i iç yöntemi içinde de adaptör ayarlayın. Bu listeyi onDataChange() dışında kullanmak isterseniz, cevabımı bu post'dan okumanızı öneririz.

+0

Bağdaştırıcıyı iç onDataChange() içine ayarlayacağım, "for" döngüsünün içine koyacağım ve aslında içindeki her nesne için ayarlayacağım. Listenin nesneleri dolduğunda, "for" döngüsünden sonra yalnızca bir kez ayarlamak istiyorum. –

+0

Bunu, veritabanı yapınız ile gerçekleştiremezsiniz, çünkü iç içe geçmiş sorguları kullanmanız gerekir, bu da iki kez asenkronize veri yüklemeniz gerektiği anlamına gelir. Bu listeyi 'onDataChange()' yönteminin dışında kullanırsanız (hangi materyali yoksa) her zaman boş olacaktır. 2 ihtimalin var. Cevabımı bu [post] adresinden (https://stackoverflow.com/questions/44152775/how-to-get-value-async-in-outside-method-ondatachange) kullanabilmemiz için mükemmel bir şekilde çalışıyor veya veritabanı yapınızı değiştiriyorsunuz. sadece bir sorguya ihtiyaç vardır. –

+0

Anladığım kadarıyla, bu gönderideki cevabınız bağdaştırıcıyı "for" döngüsünden sonra yerleştirmeme yardımcı oluyor mu? Eğer yaparsa, anlamıyorum. Bu, kodumu kodumdaki koddan alma girişimim: https://pastebin.com/fgWhNpDv –

İlgili konular