Cloud Firestore w PWA
![cloud firestore firebase](https://i0.wp.com/panzpogodna.pl/wp-content/uploads/2020/09/firestore.jpg?fit=800%2C450&ssl=1)
Cloud Firestore, to baza danych do tworzenia aplikacji mobilnych, internetowych i serwerowych od Firebase. Dziś klika słów na ten temat, gdyż używam tego rozwiązania do serwowania danych z Arduino na PWA zainstalowane na smartfonie.
Dane z Arduino przechodzą przez serwer PHP i to właśnie on wysyła dane do Firestore a ten pcha dane na mój telefon. Arduino co 30 minut wysyła dane na serwer, gdzie zapisuję je do bazy danych i jednocześnie aktualizuję bazę Firestore o konkretne dane i dalej to Firestore pushuje dane do PWA.
Czym jest PWA?
Należy zacząć od stworzenia PWA, o której pokrótce … Aplikacje PWA są uniwersalne i można je uruchomić wszędzie tam, gdzie jest dostępna przeglądarka internetowa. PWA to jednak niejedyna możliwość tworzenia aplikacji na wszystkie dostępne platformy. Bazuje ona na pilku manifest.json oraz service-worker.js, które definiują kształt i formę PWA. Oba pe pliki należy zlinkować z szblonem strony – manifest.json w sekcji <head>
a service-worker jako <script>
. Przykłady plików poniżej:
manifest.json
{ "name": "Pan z Pogodna", "short_name": "Pan z Pogodna", "lang": "pl-PL", "start_url": "./pwa", "display": "standalone", "theme_color": "#171916", "background_color": "#171916", "icons": [ { "src": "./assets/img/icons/icon-72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "./assets/img/icons/icon-96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "./assets/img/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png" }, { "src": "./assets/img/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "./assets/img/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "./assets/img/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "./assets/img/icons/icon-384x384.png", "sizes": "384x384", "type": "image/png" }, { "src": "./assets/img/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ], "prefer_related_applications": true }
service worker.js
const staticCacheName = 'site-statics-v3'; const dynamicCache = 'site-dynamic-v2'; const assets=[ '/', '/index.php', '/assets/global/plugins/font-awesome/css/font-awesome.min.css', ]; self.addEventListener('install', evt => { console.log('sw has been installed'); evt.waitUntil( caches.open(staticCacheName).then(cache => { console.log("caching assets"); //cache.add() cache.addAll(assets); }) ) }); self.addEventListener('activate', evt => { console.log('sw has been activated'); evt.waitUntil( caches.keys().then(keys =>{ //console.log(keys); return Promise.all(keys .filter (key => key !== staticCacheName) .map(key => caches.delete(key)) ) }) ); }); //fetch event self.addEventListener('fetch', evt =>{ console.log('fetch event', evt); if(evt.request.url.indexOf('firestore.googleapis.com') === -1){ evt.respondWith( caches.match(evt.reguest).then(cacheRes => { return cacheRes || fetch(evt.request).then(fetchRes => { return caches.open(dynamicCache).then (cache => { cache.put(evt.request.url, fetchRes.clone()); return fetchRes; }) }); }) ) } });
Nie będę się rozwodzić nad tym, co wyżej wypisany service-worker dokładnie robi – generalnie się inicjalizuje, cachuje assety i panuje nad requestami lecącymi z firestore.googleapis.com i to powinno wystarczyć. Warto zaznaczyć, że service-worker zadziała i wystartuje tylko w domenach z certyfikatem ssl, czyli zaczynających się od https . Trzeba zarejestrować naszego service-workera, którego dodaliśmy do strony. Można to zrobić tak:
<script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then((reg) => console.log('service worker registered !', reg)) .catch((err) => console.log('error', err)); } </script>
Uruchomoiny servie-worker to warunek konieczny do działania pushowania danych na stronę, upewnij się, że w konsoli zobaczysz service worker registered !
w swojej konsoli tylko poprzez https.
Konto Firestore
Aby rozpocząć przygodę z Firestore nalezy założyć konto (jest to usługa googlowa) na firebase.google.com i utworzyć nowy projekt, podać jego nazwę itp a następnie stworzyć aplikację – w tym przypadku aplikację sieciową. Podać jej nazwę i tym podobne i wkleić uzyskany kod na swoją stronę.
<!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.21.0/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.google.com/docs/web/setup#available-libraries --> <script src="https://www.gstatic.com/firebasejs/7.21.0/firebase-analytics.js"></script> <script> // Your web app's Firebase configuration // For Firebase JS SDK v7.20.0 and later, measurementId is optional var firebaseConfig = { apiKey: "xxx-xxxx", authDomain: "xxxxx-xxx.firebaseapp.com", databaseURL: "https://xxxxxx-46905.firebaseio.com", projectId: "xxxxxx-xxxxxx", storageBucket: "xxxx-xxxx.appspot.com", messagingSenderId: "xxxxx", appId: "1:xxxxxx:web:xxxxxa", measurementId: "G-xxxxx" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); firebase.analytics(); </script>
Kolejnym krokiem jest stworzenie bazy danych Cloud Firestore. Do tego trzeba z menu głównego z lewej strony wybrać Cloud Firestore i utworzyć nowa bazę danych. I już prawie koniec…. Stwórz kolekcję, dokument i dodaj do niej pola, które chcesz aktualizować i pobierać w dalszej części swojej aplikacji. W dalszej części postaram się zaprezentować jak z poziomu php aktualizować pola poprzez rest api i jak pobierać dane przez javascript. Póki co zobacz, jak wygląda przykładowa baza danych
![](https://i0.wp.com/panzpogodna.pl/wp-content/uploads/2020/09/cloudfirestore-1024x516.jpg?resize=1024%2C516)
Aktualizacja bazy przez REST API
Aby aktualizować rekordy poprzez PHP stwórz na serwerze plik php który będziesz wywoływać i z niego będzie wysyłać dane. Do tego uzyje CURLa, który prosto zaprezentuje udane zapytanie, oto przykład:
$ch = curl_init("https://firestore.googleapis.com/v1/projects/<projectId>/databases/(default)/documents/pzp/sensors"); $json='{ "fields": {"brightness":{"stringValue": "'.$brightness.'"}}, "fields": {"humBasement":{"stringValue": "'.$humidityPiwnica.'"}}, "fields": {"humGarage":{"stringValue": "'.$humidityGaraz.'"}}, "fields": {"humOutside":{"stringValue": "'.$humidityOutside.'"}}, "fields": {"humPralnia":{"stringValue": "'.$humidityPralnia.'"}}, "fields": {"ip":{"stringValue": "'.$ip.'"}}, "fields": {"pressure":{"stringValue": "'.$pressure.'"}}, "fields": {"tempBasement":{"stringValue": "'.$temperaturaPiwnica.'"}}, "fields": {"tempGarage":{"stringValue": "'.$temperaturaGaraz.'"}}, "fields": {"tempOutside":{"stringValue": "'.$temperaturaOutside.'"}}, "fields": {"tempPralnia":{"stringValue": "'.$temperaturaPralnia.'"}}, "fields": {"lastSynchro":{"stringValue": "'.$nowDate.'"}} }'; $headers = array(); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); curl_setopt($ch, CURLOPT_HTTPHEADER,$headers); $response = curl_exec($ch); curl_close($ch);
I to tyle… zwróć uwage, że w linku $ch
musisz ustawić projectId z kawałka kodu jaki przekeliłeś na stronę oraz ścieżkę do swoich pól w bazie – w moim przypadku /pzp/sensors. Nastepnie w $json
tworzysz pola z wartościami jakie chcesz zapisać. Każde wysłanie curla spowoduje nadpisanie poprzednich wartości.
Odczyt danych z Cloud Firestore
Aby przesłać, pushować dane z Cloud Firestore do swojej strony, aplikacji czy PWA z wykorzystaniem javascriptu należy zainicjować zmienną db
, najlepiej zaraz po tym jak zainicjalizowany został firebase – czyli w miejscu gdzie przekopiowałeś kod na swoją stronę.
firebase.initializeApp(firebaseConfig); const db = firebase.firestore(); firebase.analytics();
Gdy już jest stworzona zmienna db
, pozostaje się do nie odwołać dalej w javascripcie, na przykład tak:
db.enablePersistence() .catch(err => { if(err.code == 'failed-precondition'){ console.log('faled'); }else if(err.code == 'unimplemented'){ console.log('faled'); } }); db.collection("pzp").doc("sensors") .onSnapshot(function(doc) { // console.log(doc); console.log(doc.data().tempOutside); console.log(doc.data().humOutside); console.log(doc.data().pressure); console.log(doc.data().tempBasement); console.log(doc.data().humBasement); console.log(doc.data().tempPralnia); console.log(doc.data().humPralnia); console.log(doc.data().tempGarage); console.log(doc.data().humGarage); console.log(doc.data().lastSynchro); });
To tyle. Zasada działania jest taka, że ilekroć dane w Firestore zostaną zmienione czy to „z palca” czy poprzez wspomnianego CURL’a czy jeszcze inaczej, tyle razy zaktualizowane dane trafią do twojej aplikacji automatycznie, co można sprawdzić podglądając konsolę.
Opublikowano: 21 września, 2020 przez Pan z Pogodna