Mit Vue.js und Firestore voll durchstarten
Veröffentlicht: 2022-03-10Google Firebase hat eine neue Datenspeicherungsmöglichkeit namens „Firestore“ (derzeit in der Beta-Phase), die auf dem Erfolg der Firebase Realtime Database aufbaut, aber einige raffinierte Funktionen hinzufügt. In diesem Artikel richten wir die Grundlagen einer Web-App mit Vue.js und Firestore ein.
Nehmen wir an, Sie haben diese großartige Idee für ein neues Produkt (z. B. das nächste Twitter, Facebook oder Instagram, denn wir können nie genug soziale Netzwerke haben, oder?). Zunächst möchten Sie einen Prototyp oder ein M inimum Viable Product (MVP) dieses Produkts herstellen. Ziel ist es, den Kern der App so schnell wie möglich aufzubauen, damit Sie ihn den Benutzern zeigen, Feedback erhalten und die Nutzung analysieren können. Der Schwerpunkt liegt stark auf Entwicklungsgeschwindigkeit und schnellen Iterationen.
Aber bevor wir mit dem Bau beginnen, braucht unser erstaunliches Produkt einen Namen. Nennen wir es „Amazeballs“. Es wird legend – warte darauf – dary !
Hier mal ein Bild wie ich es mir vorstelle:
Bei unserer Amazeballs-App geht es natürlich darum, kitschige Leckerbissen Ihres Privatlebens mit Freunden in sogenannten Bällen zu teilen. Oben ist ein Formular zum Posten von Bällen, darunter die Bälle deiner Freunde.
Beim Erstellen eines MVP benötigen Sie Tools, die Ihnen die Möglichkeit geben, die wichtigsten Funktionen schnell zu implementieren, sowie die Flexibilität, Funktionen später schnell hinzuzufügen und zu ändern. Meine Wahl fällt auf Vue.js, da es sich um ein Javascript-Rendering-Framework handelt, das von der Firebase-Suite (von Google) und seiner neuen Echtzeitdatenbank namens Firestore unterstützt wird.
Auf Firestore kann direkt über normale HTTP-Methoden zugegriffen werden, was es zu einer vollständigen Backend-as-a-Service-Lösung macht, bei der Sie keine eigenen Server verwalten müssen, aber dennoch Daten online speichern.
Klingt mächtig und einschüchternd, aber keine Sorge, ich führe Sie durch die Schritte zum Erstellen und Hosten dieser neuen Web-App. Beachten Sie, wie groß die Bildlaufleiste auf dieser Seite ist; Es gibt nicht viele Schritte. Wenn Sie außerdem wissen möchten, wo Sie die einzelnen Code-Snippets in einem Code-Repository ablegen müssen, können Sie eine vollständig ausgeführte Version von Amazeballs auf GitHub sehen.
Lasst uns beginnen
Wir beginnen mit Vue.js. Es ist großartig für Javascript-Anfänger, da Sie mit HTML beginnen und ihm nach und nach Logik hinzufügen. Aber unterschätzen Sie nicht; Es enthält viele leistungsstarke Funktionen. Diese Kombination macht es zu meiner ersten Wahl für ein Frontend-Framework.
Vue.js verfügt über eine Befehlszeilenschnittstelle (CLI) für Gerüstprojekte. Wir werden das verwenden, um die Barebones schnell einzurichten. Installieren Sie zuerst die CLI und verwenden Sie sie dann, um ein neues Projekt basierend auf der Vorlage „webpack-simple“ zu erstellen.
npm install -g vue-cli vue init webpack-simple amazeballs
Wenn Sie den Schritten auf dem Bildschirm folgen ( npm install
und npm run dev
), öffnet sich ein Browser mit einem großen Vue.js-Logo.
Herzlichen Glückwunsch! Das war einfach.
Als nächstes müssen wir ein Firebase-Projekt erstellen. Gehen Sie zu https://console.firebase.google.com/ und erstellen Sie ein Projekt. Ein Projekt beginnt im kostenlosen Spark-Plan, der Ihnen eine begrenzte Datenbank (1 GB Daten, 50.000 Lesevorgänge pro Tag) und 1 GB Hosting bietet. Das ist mehr als genug für unseren MVP und leicht aktualisierbar, wenn die App an Zugkraft gewinnt.
Klicken Sie auf „Firebase zu Ihrer Web-App hinzufügen“, um die benötigte Konfiguration anzuzeigen. Wir werden diese Konfiguration in unserer Anwendung verwenden, aber in einer netten Vue.js-Manier mit Shared State.
Installieren Sie zuerst npm install firebase
und erstellen Sie dann eine Datei namens src/store.js . Dies ist der Punkt, an dem wir den freigegebenen Zustand versetzen werden, damit jede Vue.js-Komponente unabhängig vom Komponentenbaum darauf zugreifen kann. Unten ist der Inhalt der Datei. Der Zustand enthält vorerst nur einige Platzhalter.
import Vue from 'vue'; import firebase from 'firebase/app'; import 'firebase/firestore'; // Initialize Firebase, copy this from the cloud console // Or use mine :) var config = { apiKey: "AIzaSyDlRxHKYbuCOW25uCEN2mnAAgnholag8tU", authDomain: "amazeballs-by-q42.firebaseapp.com", databaseURL: "https://amazeballs-by-q42.firebaseio.com", projectId: "amazeballs-by-q42", storageBucket: "amazeballs-by-q42.appspot.com", messagingSenderId: "972553621573" }; firebase.initializeApp(config); // The shared state object that any vue component can get access to. // Has some placeholders that we'll use further on! export const store = { ballsInFeed: null, currentUser: null, writeBall: (message) => console.log(message) };
Jetzt fügen wir die Firebase-Teile hinzu. Ein Stück Code zum Abrufen der Daten aus dem Firestore:
// a reference to the Balls collection const ballsCollection = firebase.firestore() .collection('balls'); // onSnapshot is executed every time the data // in the underlying firestore collection changes // It will get passed an array of references to // the documents that match your query ballsCollection .onSnapshot((ballsRef) => { const balls = []; ballsRef.forEach((doc) => { const ball = doc.data(); ball.id = doc.id; balls.push(ball); }); store.ballsInFeed = balls; });
Und ersetzen Sie dann die Funktion writeBall
durch eine, die tatsächlich einen Schreibvorgang ausführt:
writeBall: (message) => ballsCollection.add({ createdOn: new Date(), author: store.currentUser, message })
Beachten Sie, wie die beiden vollständig entkoppelt sind. Wenn Sie in eine Sammlung einfügen, wird der onSnapshot
ausgelöst, weil Sie ein Element eingefügt haben. Dies erleichtert die Zustandsverwaltung erheblich.
Jetzt haben Sie ein gemeinsames Zustandsobjekt, auf das jede Vue.js-Komponente problemlos zugreifen kann. Lass es uns gut gebrauchen.
Sachen posten!
Lassen Sie uns zuerst herausfinden, wer der aktuelle Benutzer ist.
Firebase verfügt über Authentifizierungs-APIs, die Ihnen bei der Arbeit helfen, Ihren Benutzer kennenzulernen. Aktivieren Sie die entsprechenden in der Firebase-Konsole unter Authentication → Sign In Method . Im Moment werde ich Google Login verwenden – mit einer sehr unausgefallenen Schaltfläche.
Firebase bietet Ihnen keine Schnittstellenhilfe, daher müssen Sie Ihre eigenen „Login with Google/Facebook/Twitter“-Schaltflächen und/oder Benutzernamen-/Passwort-Eingabefelder erstellen. Ihre Login-Komponente wird wahrscheinlich ungefähr so aussehen:
<template> <div> <button @click.prevent="signInWithGoogle">Log in with Google</button> </div> </template> <script> import firebase from 'firebase/app'; import 'firebase/auth'; export default { methods: { signInWithGoogle() { var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); } } } </script>
Jetzt gibt es noch ein weiteres Teil des Login-Puzzles, und zwar das Abrufen der Variable currentUser
im Store. Fügen Sie diese Zeilen zu Ihrer store.js hinzu :
// When a user logs in or out, save that in the store firebase.auth().onAuthStateChanged((user) => { store.currentUser = user; });
Aufgrund dieser drei Zeilen ändert sich bei jeder Änderung des aktuell angemeldeten Benutzers (an- oder abmelden) auch store.currentUser
. Posten wir ein paar Bälle!
Das Eingabeformular ist eine separate Vue.js-Komponente, die wie folgt mit der Funktion writeBall
in unserem Store verbunden ist:
<template> <form @submit.prevent="formPost"> <textarea v-model="message" /> <input type="submit" value="DUNK!" /> </form> </template> <script> import { store } from './store'; export default { data() { return { message: null, }; }, methods: { formPost() { store.writeBall(this.message); } }, } </script>
Fantastisch! Jetzt können sich die Leute anmelden und mit dem Posten von Bällen beginnen. Aber warten Sie, uns fehlt die Autorisierung. Wir möchten, dass Sie Bälle nur selbst posten können, und hier kommen die Firestore-Regeln ins Spiel. Sie bestehen aus Javascript-artigem Code, der Zugriffsrechte auf die Datenbank definiert. Sie können sie über die Firestore-Konsole eingeben, aber Sie können sie auch über die Firebase-CLI von einer Datei auf der Festplatte installieren. Installieren und starten Sie es wie folgt:
npm install -g firebase-tools firebase login firebase init firestore
Sie erhalten eine Datei mit dem Namen firestore.rules , in der Sie die Autorisierung für Ihre App hinzufügen können. Wir möchten, dass jeder Benutzer seine eigenen Bälle einfügen kann, aber nicht die eines anderen einfügen oder bearbeiten kann. Das folgende Beispiel funktioniert gut. Es erlaubt jedem, alle Dokumente in der Datenbank zu lesen, aber Sie können nur einfügen, wenn Sie angemeldet sind und die eingefügte Ressource ein Feld „Autor“ hat, das mit dem aktuell angemeldeten Benutzer identisch ist.
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read: if true; allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.author; } } }
Es sieht aus wie ein paar Codezeilen, ist aber sehr leistungsfähig und kann sehr schnell komplex werden. Firebase arbeitet an besseren Tools für diesen Teil, aber im Moment ist es Trial-and-Error, bis es sich so verhält, wie Sie es möchten.
Wenn Sie firebase deploy
ausführen, werden die Firestore-Regeln bereitgestellt und sichern Ihre Produktionsdaten in Sekunden.
Hinzufügen von Serverlogik
Auf Ihrer Homepage möchten Sie eine Chronik mit den Bällen Ihrer Freunde sehen. Je nachdem, wie Sie bestimmen möchten, welche Bälle ein Benutzer sieht, könnte das Ausführen dieser Abfrage direkt in der Datenbank einen Leistungsengpass darstellen. Eine Alternative besteht darin, eine Firebase Cloud-Funktion zu erstellen, die bei jedem geposteten Ball aktiviert und an die Wände aller Freunde des Autors angehängt wird. Auf diese Weise ist es asynchron, nicht blockierend und schließlich konsistent. Oder mit anderen Worten, es wird dort ankommen.
Um die Beispiele einfach zu halten, mache ich eine kleine Demo, in der ich erstellte Bälle anhöre und ihre Botschaft ändere. Nicht, weil das besonders nützlich ist, sondern um Ihnen zu zeigen, wie einfach es ist, Cloud-Funktionen zum Laufen zu bringen.
const functions = require('firebase-functions'); exports.createBall = functions.firestore .document('balls/{ballId}') .onCreate(event => { var createdMessage = event.data.get('message'); return event.data.ref.set({ message: createdMessage + ', yo!' }, {merge: true}); });
Oh, warte, ich habe vergessen, dir zu sagen, wo du diesen Code schreiben sollst.
firebase init functions
Dadurch wird das Funktionsverzeichnis mit einer index.js erstellt . Das ist die Datei, in die Sie Ihre eigenen Cloud-Funktionen schreiben können. Oder kopieren Sie meine, wenn Sie davon sehr beeindruckt sind.
Cloud Functions bieten Ihnen einen guten Ort, um verschiedene Teile Ihrer Anwendung zu entkoppeln und sie asynchron kommunizieren zu lassen. Oder im architektonischen Zeichenstil:
Letzter Schritt: Bereitstellung
Firebase stellt dafür seine Hosting-Option zur Verfügung, die Sie über die Firebase-CLI verwenden können.
firebase init hosting
Wählen Sie dist
als öffentliches Verzeichnis und dann „Ja“, um alle URLs in index.html
umzuschreiben. Mit dieser letzten Option können Sie vue-router verwenden, um schöne URLs in Ihrer App zu verwalten.
Jetzt gibt es eine kleine Hürde: Der dist
-Ordner enthält keine index.html
-Datei, die auf den richtigen Build Ihres Codes verweist. Um dies zu beheben, fügen Sie Ihrer package.json
ein npm-Skript hinzu:
{ "scripts": { "deploy": "npm run build && mkdir dist/dist && mv dist/*.* dist/dist/ && cp index.html dist/ && firebase deploy" } }
Führen Sie jetzt einfach npm deploy
aus, und die Firebase-CLI zeigt Ihnen die URL Ihres gehosteten Codes an!
Wann diese Architektur verwendet werden sollte
Dieses Setup ist perfekt für einen MVP. Wenn Sie dies zum dritten Mal getan haben, haben Sie in wenigen Minuten eine funktionierende Web-App – unterstützt durch eine skalierbare Datenbank, die kostenlos gehostet wird. Sie können sofort mit dem Erstellen von Funktionen beginnen.
Außerdem gibt es viel Platz zum Wachsen. Wenn Cloud-Funktionen nicht leistungsfähig genug sind, können Sie beispielsweise auf eine traditionelle API zurückgreifen, die auf Docker in Google Cloud ausgeführt wird. Außerdem können Sie Ihre Vue.js-Architektur mit vue-router
und vuex
und die Leistung von Webpack nutzen, das in der vue-cli-Vorlage enthalten ist.
Es sind jedoch nicht nur Regenbögen und Einhörner. Der berüchtigtste Vorbehalt ist die Tatsache, dass Ihre Kunden sofort mit Ihrer Datenbank sprechen. Es gibt keine Middleware-Schicht, mit der Sie die Rohdaten in ein für den Client einfacheres Format umwandeln können. Sie müssen es also kundenfreundlich speichern. Wann immer Ihre Kunden Änderungen anfordern, werden Sie es ziemlich schwierig finden, Datenmigrationen auf Firebase durchzuführen. Dazu müssen Sie einen benutzerdefinierten Firestore-Client schreiben, der jeden Datensatz liest, transformiert und zurückschreibt.
Nehmen Sie sich Zeit, um sich für Ihr Datenmodell zu entscheiden. Wenn Sie Ihr Datenmodell später ändern müssen, ist die Datenmigration Ihre einzige Option.
„
Was sind Beispiele für Projekte, die diese Tools verwenden? Zu den großen Namen, die Vue.js verwenden, gehören Laravel, GitLab und (für die Niederländer) nu.nl. Firestore befindet sich noch in der Beta-Phase, also noch nicht viele aktive Benutzer, aber die Firebase-Suite wird bereits von National Public Radio , Shazam und anderen verwendet. Ich habe gesehen, wie Kollegen Firebase für das Unity-basierte Spiel Road Warriors implementiert haben, das in den ersten fünf Tagen über eine Million Mal heruntergeladen wurde. Es kann einiges auslasten und ist sehr vielseitig mit Clients für das Web, native Mobilgeräte, Unity und so weiter.
Wo melde ich mich an?!
Wenn Sie mehr erfahren möchten, ziehen Sie die folgenden Ressourcen in Betracht:
- Arbeitsbeispiel, das den gesamten obigen Code enthält
- Dokumentation zu Vue.js, vue-router, vue-cli
- Dokumentation zu Firebase
- Eine unterhaltsame Möglichkeit, Firebase besser kennenzulernen – ihr YouTube-Blog
Viel Spaß beim Codieren!