2017-04-24 11 views
0

Ich habe diese Funktion:Firebase OnDataChange kehrt Nullwert

public String checkOnline(String fId) { 

     DatabaseReference onlineUser = FirebaseDatabase.getInstance().getReference().child("online").child(fId); 

     onlineUser.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       Online post = dataSnapshot.getValue(Online.class); 
       uOnline = post.timestamp; 

       different = getDate().getTime() - uOnline; 
       different = TimeUnit.MILLISECONDS.toMinutes(different); 

       if(different < 1){ 
        ifOnline = "donline.setVisibility(View.VISIBLE);"; 
       } else { 
        ifOnline = "donline.setVisibility(View.GONE);"; 
       } 


      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       System.out.println("The read failed: " + databaseError.getCode()); 
      } 
     }); 

     return ifOnline; 

    } 

ifOnline ist ein String

I checkOnline Funktion aufrufen und die Funktion ausführt, für jeden Benutzer und ruft beide Aussagen (1 für jeder Benutzer natürlich).

Das Problem ist, dass checkOnline Null zurückgibt, auch wenn die Anweisungen gut ausgeführt wurden. Wo ist das Problem? Liegt es daran, dass onDataChange ungültig ist?

Ich habe keine Ahnung, wo das Problem ist, wie die ifOnline der Klasse privat ist, also sobald es auf den Wert zugewiesen wird, sollte die currect Wert zurück ..

Datenstruktur hinzugefügt:

Online-Datenbankstruktur:

Online -> userId: status (string) 
        timestamp (long) 
+0

Bitte geben Sie uns Ihre Datenbankstruktur an. –

+0

Verwenden Sie Ihre Firebase-Konsole, um Ihre Datenbankstruktur als JSON-Datei herunterzuladen. –

+0

Diese Funktion verwendet 1 JSON-Baumobjekt, das ich zur Verfügung gestellt habe – AlwaysConfused

Antwort

0

Es ist, weil OnDataChange asynchron aufgerufen wird und die Anweisung return ifOnline wird ausgeführt, bevor OnDataChange aufgerufen wurde . Natürlich vorausgesetzt, dass mit Ihrer Datenbank alles in Ordnung ist.

+0

Wie ist das? onDataChange ist innerhalb der checkOnline-Funktion, also muss onDataChange den Wert zuweisen, bevor checkOnline irgendetwas zurückgibt? – AlwaysConfused

+0

Nein, 'onDataChange' ist eine Methode des 'ValueEventListener'-Objekts, die Sie von einer anonymen Klasse an die' addValueEventListener'-Methode übergeben. Und der 'ValueEventListener' ruft die 'onDataChange'-Methode auf, wenn das Herunterladen von der Datenbank abgeschlossen ist und alles asynchron (in einem anderen Thread) ausgeführt wird. Sie können sich also nicht darauf verlassen, dass 'onDataChange' aufgerufen wird, wenn Sie' checkOnline' aufrufen. –

+0

Sie haben Recht. Ich habe den Code anders implementiert und es funktioniert jetzt gut. Ich löste die Funktion vollständig und fügte onDataChange direkt zu einer anderen Funktion hinzu, von der die checkOnline hieß – AlwaysConfused

0

Bitte versuchen Sie diesen Code zu verwenden:

public String checkOnline(String fId) { 

    DatabaseReference onlineUser = FirebaseDatabase.getInstance().getReference().child("online").child(fId); 

    onlineUser.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
     Long post = dataSnapshot.child("timestamp").getValue(Long.class); 
     uOnline = post.timestamp; 

     different = getDate().getTime() - uOnline; 
     different = TimeUnit.MILLISECONDS.toMinutes(different); 

     if(different < 1){ 
      ifOnline = "donline.setVisibility(View.VISIBLE);"; 
     } else { 
      ifOnline = "donline.setVisibility(View.GONE);"; 
     } 


     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
     System.out.println("The read failed: " + databaseError.getCode()); 
     } 
    }); 

    return ifOnline; 
} 

Das Problem ist auf dieser Linie: Online post = dataSnapshot.getValue(Online.class);

benötigen Sie den Timestamp als Long zu bekommen. Ich hoffe es hilft.

+0

Danke dafür, aber das macht überhaupt keinen Unterschied, da ich lange von Online-Klasse – AlwaysConfused

+1

komme Oh, verstehe ich jetzt. In diesem Fall ist "Dusan Jovanov" korrekt. –

1

Wie u weiß jetzt, dass onDataChange() asynchron ausgeführt wird, so dass i checkOnline(String fId) Rückkehr nichtig machen vorschlagen werde und eine Funktion wie checkOnlineResponse(ifOnline) in onDataChange() anrufen und Rest Ihrer Logik in der checkOnlineResponse(ifOnline) Funktion ausführen. Hoffe es hilft.

Verwandte Themen