2017-10-04 1 views
0

Ich versuche, ein Benutzerprofil aus einer Firebase-DB zu erhalten. Dann benutze ich die Informationen des Benutzers und möchte TextViews im Layout meines Fragments setzen, um die individuellen Werte des Benutzers zu reflektieren.Android Firebase - Lesen von Daten aus Firebase vor dem Aufblasen des Layouts

Das Problem ist, dass die RootViw zurückgegeben wird, bevor das Profil des Benutzers erhalten. Und so bekomme ich einen Null-Objekt Referenzfehler.

Mein Verständnis des Lebenszyklus des Fragments ist, dass onCreate() zuerst erstellt wird und so habe ich versucht, den DB-Code dort zu platzieren, aber ich bekomme das gleiche Problem. Ich dachte dann, dass, wenn der Zugriff auf die DB langsamer ist als meine onCreateView(), ich einen Thread.sleep() Timer setze, um auf den DB-Aufruf zu warten und dann den Rest meines Codes auszuführen. Was ich weiß, ist eine dumme Lösung, aber wollte nur meine Theorie testen; das ist auch gescheitert, so offensichtlich ist mein Verständnis falsch.

Wo sollte ich meinen DB-Aufruf platzieren, so dass er abgeschlossen ist, bevor mein rootView zurückgegeben wird? Warum funktioniert das Einfügen des DB-Listeners in OnCreate() nicht und warum funktioniert die Thread.sleep() - Verzögerung nicht?

Leader Fragment

public class Leaderboard extends Fragment{ 

    private FirebaseAuth mFirebaseAuth; 
    private DatabaseReference mUserDatabaseReference; 

    private User user; 

    private TextView scoreView; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_leaderboard, 
             container, false); 

     scoreView = rootView.findViewById(R.id.leaderboard_score); 

     mFirebaseAuth = FirebaseAuth.getInstance(); 
     final String userUID = mFirebaseAuth.getCurrentUser().getUid(); 

     mUserDatabaseReference = 
       FirebaseDatabase.getInstance().getReference("users"); 

     mUserDatabaseReference.addListenerForSingleValueEvent(new 
                 ValueEventListener() { 

      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       if (snapshot.hasChildren()) { 
        for (DataSnapshot messageSnap: snapshot.getChildren()) { 
         if(messageSnapshot.getKey().equals(userUID)) { 
          user = messageSnapshot.getValue(User.class); 
         }}}} 
      @Override 
      public void onCancelled(DatabaseError databaseError) {} 
     }); 

     //Causes error because user==null 
     scoreView.setText("Score: " + user.getScore()); 

     return rootView; 
    } 
} 

Antwort

1

Alle Firebase-APIs sind asynchron. Sie sollten erwarten, dass Listener nach beliebig lange Zeit aufgerufen werden können, basierend auf der Qualität der Hardware und der Netzwerkverbindung. Verwenden Sie niemals Thread.sleep(), um zu versuchen, das Timing der Dinge zu kontrollieren - das ist ein Anti-Pattern.

Mein Vorschlag an Sie ist, einen "Lade" -Bildschirm in onCreateView() aufzublasen, um sofort anzuzeigen, so dass der Benutzer nicht auf einen leeren Bildschirm schauen muss, wenn Ihr Fragment startet. Wenn Ihr Listener dann mit den Daten aufgerufen wird, die Sie anzeigen möchten, fügen Sie nach Bedarf weitere Ansichten hinzu oder aktualisieren Sie sie.

0

Warum die Partitur nicht festgelegt, nachdem Sie das DB-Ergebnis zu erhalten?

mUserDatabaseReference.addListenerForSingleValueEvent(new 
                ValueEventListener() { 

     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      if (snapshot.hasChildren()) { 
       for (DataSnapshot messageSnap: snapshot.getChildren()) { 
        if(messageSnapshot.getKey().equals(userUID)) { 
         user = messageSnapshot.getValue(User.class); 
        } 
       } 
       scoreView.setText("Score: " + user.getScore()); 
       }} 
     @Override 
     public void onCancelled(DatabaseError databaseError) {} 
    }); 
+0

Diese Lösung funktioniert, aber ich glaube, ich fühlte, dass der Hörer von den Aussagen getrennt sein sollte, die die Sicht ändern? Vielleicht ist mein Denken falsch? Wie auch immer, danke! – Vindictive

Verwandte Themen