6 Hacker News Reader met Firebase backend

Leerdoelen

Na het maken van deze app wordt van je verwacht dat je:

  • weet hoe de Android Lifecycle er uit ziet en zijn verschillende methodes kunt gebruiken
  • weet hoe je Firebase in een project installeert
  • een referentie naar een dataset in Firebase kunt maken
  • EventListeners aan een Firebase referentie kunt koppelen
  • diverse typen data uit een DataSnapshot kunt halen
  • een model klasse kunt maken en hiervan een object kunt maken met behulp van een DataSnapshot
  • een Toast kunt maken

Opdracht 1

Bekijk onderstaand filmpje en maak de app.

Gebruikte methodes/klassen

De Android Lifecycle

Alleen als je app niet (meer) op de achtergrond actief is, wordt de onCreate methode aangeroepen. Dit gebeurt als de app voor het eerst wordt gestart of wanneer het systeem of de gebruiker de app heeft beëindigd en de onDestroy methode is aangeroepen. Android kent een aantal van deze lifecycle methoden die je kunt gebruiken om processen te starten en te stoppen.

android lifecycle
startmethode stopmethode
onCreate onDestroy
onStart/onRestart onStop
onResume onPause

Om er voor te zorgen dat de app stopt met het binnenhalen van data als hij niet op de voorgrond draait, kun je bijvoorbeeld de onPause en de onResume methode gebruiken om de Firebase listeners uit/in te schakelen.

Firebase

Om Firebase te kunnen gebruiken moet je het in je project installeren. Dit is vrij eenvoudig in Android Studio. Ga naar File, kies Project Structure..., Kies Cloud en vink Firebase aan. Je hoeft nu alleen nog de volgende regel code in de onCreate methode toe te voegen:

Firebase.setAndroidContext(this);

Data van Firebase kun je vinden met behulp van een url. De volgende regel code maakt een referentie naar de id's van New Stories.

Firebase ref = new Firebase("https://hacker-news.firebaseio.com/v0/newstories");

Listeners

Om de data daadwerkeijk in je app binnen te halen moet je een listener aan de Firebase referentie koppelen. Deze haalt allereerst de data op en zorgt er vervolgens voor dat wijzigingen in de dataset worden gesynchroniseerd met de app. Je kunt verschillende soorten listeners aan een Firebase referentie koppelen:

methode beschrijving
addValueEventListener luistert naar verandering van waarden in de dataset. Met de dataSnapshot parameter van de methode onDataChange wordt de gehele vernieuwde dataset doorgegeven.
addChildEventListener wanneer sprake is van een lijst met items luistert deze listener naar veranderingen in de children van de lijst. De methoden onChildAdded, onChildChanged, onChildRemoved en onChildMoved geven alleen de data van het veranderde item door.
addListenerForSingleValueEvent Haalt data binnen en wordt daarna verwijderd. Deze listener blijft dus niet luisteren naar wijzigingen in de dataset en hoeft dus ook niet te worden verwijderd.

Voor een uitgebreide uitleg zie de Android guide van Firebase.

Het volgende codefragment koppelt een ValueEventListener aan de referentie met de id's van de artikelen en haalt met een for-each loop één voor één de id's op:

Firebase ref = new Firebase("https://hacker-news.firebaseio.com/v0/newstories");
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot ) {
        for (DataSnapshot idSnapShot : dataSnapshot.getChildren()) {
            Long id = (Long) idSnapShot.getValue();
            //TODO haal artikel mbv id
        }
    }
    @Override
    public void onCancelled(FirebaseError firebaseError) {
    }
}

DataSnapshot

Data wordt door Firebase doorgegeven met een DataSnapshot Dit is de dataset van de Firebase referentie. Dit kan een enkel item of een lijst met items zijn. In de Hacker News reader zijn de volgende methodes van DataSnapshot gebruikt:

methode beschrijving return-type
child(String naam) verwijst naar een property van de DataSnapshot waarbij de naam (key) wordt meegegeven als String. De methode geeft een DataSnapshot object terug. DataSnapshot
getChildren() geeft alle kinderen van een DataSnapshot in de vorm van een lijst met DataSnapshots (waar je doorheen kunt loopen). Iterable<DataSnapshot>
exists() checkt of een bepaalde property in de DataSnapshot aanwezig is. boolean
getValue() geeft de waarde van een DataSnapshot Object (moet gecast worden naar werkelijke type)

In de uitwerking van de HN reader worden de methodes child en getValue gebruikt om de Strings met de titel en de url van het artikel op te halen.

String title = (String) dataSnapshot.child("title").getValue();
String url = (String) dataSnapshot.child("url").getValue();

Een model-klasse gebruiken

Data van een DataSnapshot kun je gebruiken om een object van een model-klasse te maken. Eigenschappen waar zo'n model klasse aan moet voldoen:

In de Android guide op de Firebase site wordt als voorbeeld een model-klasse BlogPost gebruikt:

public class BlogPost {
  private String author;
  private String title;

  // lege constructor
  public BlogPost() {}

  // getters
  public String getAuthor() {
    return author;
  }
  public String getTitle() {
    return title;
  }
}

In het volgende codefragment wordt met behulp van de overloaded methode getValue van DataSnapshot een object van de klasse BlogPost gemaakt.

// Get a reference to our posts
Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");
// Attach an listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
      System.out.println("There are " + snapshot.getChildrenCount() + " blog posts");
      for (DataSnapshot postSnapshot: snapshot.getChildren()) {
        BlogPost post = postSnapshot.getValue(BlogPost.class);
        System.out.println(post.getAuthor() + " - " + post.getTitle());
      }
  }
  @Override
  public void onCancelled(FirebaseError firebaseError) {
      System.out.println("The read failed: " + firebaseError.getMessage());
  }
});

Opdracht 2

Verander de reader zodat gebruik wordt gemaakt van een klasse Artikel. Let op dat gehele getallen in Firebase altijd van het type Long zijn. De property kids bestaat uit een reeks gehele getallen. Hier kun je een List van maken.

Een Toast maken

Een Toast is een berichtje dat gedurende enkele seconden in beeld komt en de gebruiker ergens over informeert.

De volgende regel code maakt een Toast die de gebruiker informeert dat de lijst met artikelen is ververst:

Toast.makeText(getApplicationContext(), "Lijst ververst", Toast.LENGTH_SHORT).show();