0

In meiner android app starte ich einen Dienst, wenn der Benutzer die App beendet:Firebase-Datenbank-Benachrichtigungs

ArrayList<String> eventKeys = new ArrayList<>(); 
... 
Intent intent = new Intent(this, MyService.class); 
intent.putExtra("eventKeys", eventKeys); 
startService(intent); 

Dann in meinem Dienst:

public class MyService extends Service { 

    (fields)... 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 
     if (intent == null) { 
      System.out.println("ERROR"); 
      return START_REDELIVER_INTENT; 
     } 
     eventKeys = (ArrayList<String>) intent.getExtras().get("eventKeys"); 

     //here I attach listeners to firebase database 
     firebase(); 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        if (notifyMessage) { 
         sendNotification("You have a new message."); 
         stopSelf(); 
         return; 
        } 

        try { 
         System.out.println("Sleeping..."); 
         Thread.sleep(5000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }).start(); 
     return START_STICKY; 
    } 

und die folgende produziert Drucke aus Sleeping ... nur einmal und danach ERROR. Wenn ich den Null-Check entferne, bekomme ich einen Nullzeiger. Wenn ich die Firebase-Methode entferne, funktioniert es.

private void firebase(List<String> eventKeys) { 
    System.out.println("Set database listener"); 
    mDataBase = FirebaseDatabase.getInstance().getReference().child("events"); 

    for (String eventKey : eventKeys){ 

     mDataBase.child(eventKey).child("chat").addChildEventListener(new ChildEventListener() { 
      @Override 
      public void onChildAdded(DataSnapshot dataSnapshot, String s) {} 
      @Override 
      public void onChildChanged(DataSnapshot dataSnapshot, String s) { 
       //new message received 
       notifyMessage = true; 
       sendNotification("You have a new message."); 
       stopSelf(); 
      } 
      @Override 
      public void onChildRemoved(DataSnapshot dataSnapshot) {} 
      @Override 
      public void onChildMoved(DataSnapshot dataSnapshot, String s) {} 
      @Override 
      public void onCancelled(DatabaseError databaseError) {} 
     }); 
    } 
} 

funktioniert das nicht, und ich habe keine Ahnung, was zu tun.

+0

Was ist der Fehler, den Sie bekommen? –

+0

Ich bekomme keinen spezifischen Fehler. Die Benachrichtigung wird jedoch nicht gesendet, wenn ich das Kind ändere. Ich habe nicht erwähnt, dass dieser Code ausgeführt wird, wenn ich die App schließe. – Nikola

+0

Sie ignorieren mögliche Fehler beim Anhängen Ihres Hörers. Implementieren Sie 'onCancelled', wie ich gerade hier geschrieben habe: http://stackoverflow.com/documentation/firebase/5548/how-do-ilisten-for-errors-when-accessing-the-database#t=201609121647524851802 –

Antwort

1

Haben Sie Ihren Dienst in Manifest deklariert?

Sie müssen keinen neuen Thread in der Serviceklasse erstellen, da der Dienst selbst eine Hintergrundoperation ist. Überprüfen Sie documentation.

+0

Ja Ich habe das in meinem Manifest. – Nikola

+0

Wenn ich den Thread entferne, funktioniert der Code eine Weile und danach bekomme ich: 'Thread [3, tid = 29740, WaitingInMainSignalCatcherLoop, Thread: Reagieren auf Signal 3' – Nikola

+0

Abrufen von Daten aus Firebase ist eine asynchrone Methode, also nach 'fireBase()' Methodenaufruf, die Codeausführung läuft noch. Sie sollten den Thread-Job innerhalb der 'onChildChanged()' - Methode ausführen, um sicherzustellen, dass Ihre Benachrichtigung angezeigt wird, da dieser den Wert 'notifyMessage' ändern kann. Und ich kann sehen, dass Sie für jeden Schlüssel einen neuen 'childEventListener' starten und denselben booleschen Wert verwenden. –