giovedì 22 dicembre 2016

Leggere dati da Firebase Realtime Database

Per me che vengo da una esperienza SQL mettere le mani per la prima volta su un Database NoSql come quello di Firebase e' un po' spiazzante....ma ci si fa l'abitudine

Per prima cosa Firebase non gestisce i dati mentre tabelle bidimensionali a struttura rigida ma i dati vengono rapppresentati come un albero a cui sono attaccate delle derivazioni (child) i quali non e' necessario che abbiamo la stessa struttura (al di sotto di una chiave, per esempio, in un caso le proprieta' possono essere due oppure tre)


Se si editano i dati dalla Console di Firebase si vedra' che posizionando il mouse sulla root appaiono dei simboli (+ e -)..la prima volta che si usa sembra che non si abbia nessuna interazione perche' i simboli scompaiono appena si sposta il mouse



Oltre a creare i dati in modo interattivo si possono ovviamente creare anche via codice. Di seguito un esempio in Javascript commentato con le righe evidenziate in giallo
----------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Read</title>

  <!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>



</head>
<body>

<pre id="punti">

</pre>

<script>
  // Initialize Firebase

  var config = {
    apiKey: "AIzaSyAchx8oVeLUgxxxxxxxxxxxxxxxxxxxxxxx",
    authDomain: "notifica-23425.firebaseapp.com",
    databaseURL: "https://notifica-23425.firebaseio.com",
    storageBucket: "notifica-23425.appspot.com",
    messagingSenderId: "392xxxxxxxxxxxxxx"
  };
  firebase.initializeApp(config);


  var timestamp = new Date().getTime();
  console.log(timestamp);

  //vengono inseriti due nodi nella radice
  // usando il comando set vengono di fatto rimossi tutti i contenuti nel db
  var ins_punti = firebase.database().ref();

  ins_punti.set({
        l2: {
          lat: 1,
          lon: 30,
          nome: "Venezia",
          tempo: timestamp
        },
        l3: {
          lat: 33,
          lon: 40,
          nome: "Bari"
        }
      });

  //vengono aggiunti al nodo Punti due elementi. Si tratta di un append
  // e viene quindi di default inserita una chiave univoca
  ins_punti.child("Punti").push({
              lat: 13,
              lon: 33,
              nome: "Torino"
          });

  ins_punti.child("Punti").push({
                      lat: 14,
                      lon: 35,
                      nome: "Firenze"
                  });


  //vengono mostrate a video tutte le coppie del ramo "l2" del nodo in radice
  const prePunti = document.getElementById('punti');
  const dbRefPunti = firebase.database().ref().child('l2');
  dbRefPunti.on('value', snap => {
              prePunti.innerText = JSON.stringify(snap.val(),null,1);

  //con questa chiamata vengono richieste tutte le coppie chiave/valore del ramo Punti
  //da qui in poi i risultati sono visibili nel log e non a video
  firebase.database().ref().child('Punti').on('value', snap => console.log(snap.val()));

  //con questa chiamata vengono richieste tutte le coppie chiave/valore dell'ultimo nodo aggiunto alla lista del ramo Punti
  firebase.database().ref().child('Punti').limitToLast(1).on('child_added', snap => console.log(snap.val()));

  //con questa chiamata viene richiesto il valore del campo nome dell'ultimo nodo aggiunto alla lista del ramo Punti
  firebase.database().ref().child('Punti').limitToLast(1).on('child_added', snap => console.log(snap.val().nome));

  //con questa chiamata viene richiesto il valore del campo nome del nodo con lat=13 del ramo Punti
  firebase.database().ref().child('Punti').orderByChild("lat").equalTo(13).on('child_added', snap => console.log(snap.val().nome));

  firebase.database().ref().child('l2').update({lat: 133});

  //rimuove il ramo l1 dalla root
  firebase.database().ref().child('l3').remove();
});



</script>

</body>
</html>
----------------------------------------------------------------

La cosa interessante e' che le modifiche effettuate risultano essere in realtime. Se ci sono differenti client con la pagina Web aperta ed una modifica e' stata effettuata al DB questa sara' visualizzata su tutti i client senza la necesssita' di ricarica la pagina

Come per i db sql anche per Firebase e' possibile inserire la definizione delle chiavi per accelerare la ricerca e si possono definire le regole di accesso. Cio' viene effettuato nel Tab regole o rules