Dies ist eine Fortsetzung des CSS-Tricks-Artikels Einführung in Firebase und React. In dieser Lektion haben wir Fun Food Friends erstellt, eine Anwendung zur Planung Ihres nächsten Potlucks. Sie sah so aus

Wenn Sie diesen Artikel noch nicht abgeschlossen haben, schließen Sie diesen Artikel bitte zuerst ab, bevor Sie sich an diesen wagen – er baut auf dem bestehenden Code dieser Anwendung auf.
Wenn Sie diesen Artikel überspringen und direkt in diesen eintauchen möchten, können Sie dieses Repository klonen, das die fertige Version der Anwendung aus Teil eins enthält. Vergessen Sie nicht, dass Sie Ihre eigene Firebase-Datenbank erstellen und die Anmeldedaten dafür austauschen müssen, sowie npm install ausführen müssen, bevor Sie beginnen! Wenn Sie sich nicht sicher sind, wie Sie eines dieser Dinge tun, schauen Sie sich Teil eins an, bevor Sie sich in diesen stürzen.
Artikelserie
- Einführung in Firebase und React
- Benutzerauthentifizierung (Sie sind hier!)
Was wir machen werden
Heute werden wir unserer Fun Food Friends-App Authentifizierung hinzufügen, so dass nur angemeldete Benutzer sehen können, wer was zum Potluck mitbringt, und auch ihre eigenen Artikel beitragen können. Wenn sie abgemeldet sind, sieht es so aus

Wenn Benutzer nicht angemeldet sind, können sie nicht sehen, was andere zum Potluck mitbringen, und sie können auch keine eigenen Artikel hinzufügen.
Wenn angemeldet, sieht es so aus

Ihr Name wird automatisch zum Abschnitt Artikel hinzufügen hinzugefügt, und Ihr Google-Foto wird in der rechten unteren Ecke des Bildschirms angezeigt. Sie können auch nur Artikel entfernen, die Sie zum Potluck hinzugefügt haben.
Bevor wir beginnen: Holen Sie sich das CSS
Ich habe diesem Projekt zusätzliches CSS hinzugefügt, um der App etwas mehr Glanz zu verleihen. Schnappen Sie es sich von hier und fügen Sie es direkt in `src/App.css` ein!
Erste Schritte: Google-Authentifizierung in unserem Firebase-Projekt aktivieren
Melden Sie sich zunächst in der Firebase-Konsole an und besuchen Sie das Dashboard Ihrer Datenbank. Klicken Sie dann auf den Tab „Authentifizierung“. Sie sollten etwas Ähnliches wie dies sehen

Klicken Sie auf den Tab Anmeldemethode

Firebase kann die Authentifizierung handhaben, indem es den Benutzer nach einer E-Mail-Adresse und einem Passwort fragt, oder es kann auf Drittanbieter wie Google und Twitter zurückgreifen, um die Authentifizierung und den Authentifizierungsfluss für Sie zu übernehmen. Erinnern Sie sich, als Sie sich zum ersten Mal bei Firebase angemeldet haben, hat es Ihre Google-Anmeldedaten zur Authentifizierung verwendet? Firebase ermöglicht es Ihnen, diese Funktion zu Apps hinzuzufügen, die Sie erstellen.
Wir werden Google als unseren Authentifizierungsanbieter für dieses Projekt verwenden, hauptsächlich weil dies die Handhabung unseres Authentifizierungsflusses sehr einfach macht: Wir müssen uns keine Sorgen um Dinge wie Fehlerbehandlung und Passwortvalidierung machen, da Google all das für uns übernimmt. Wir müssen auch keine UI-Komponenten (außer einem An- und Abmeldebutton) erstellen, um die Authentifizierung zu handhaben. Alles wird über ein Popup verwaltet.

Fahren Sie mit der Maus über Google, wählen Sie den Bleistift auf der rechten Seite des Bildschirms aus und klicken Sie im erscheinenden Feld auf Aktiveren. Klicken Sie schließlich auf Speichern.
Klicken Sie nun auf Datenbank auf der linken Seite des Bildschirms und wechseln Sie zum Regeln-Panel. Es sollte derzeit etwa so aussehen

In der ersten Iteration unserer Fun Food Friends-App konnte jeder aus unserer Datenbank lesen und schreiben. Wir werden dies ändern, so dass nur angemeldete Benutzer in die Datenbank schreiben können. Ändern Sie Ihre Regeln so, dass sie wie folgt aussehen, und klicken Sie auf Veröffentlichen
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Diese Regeln weisen Firebase an, nur authentifizierten Benutzern das Lesen und Schreiben aus der Datenbank zu gestatten.
Vorbereitung unserer App für die Authentifizierung
Nun müssen wir zu unserer `firebase.js`-Datei zurückkehren und unsere Konfiguration aktualisieren, damit wir Google als unseren Drittanbieter-Authentifizierungsanbieter nutzen können. Derzeit sollte Ihre `firebase.js` etwa so aussehen
import firebase from 'firebase'
const config = {
apiKey: "AIzaSyDblTESEB1SbAVkpy2q39DI2OHphL2-Jxw",
authDomain: "fun-food-friends-eeec7.firebaseapp.com",
databaseURL: "https://fun-food-friends-eeec7.firebaseio.com",
projectId: "fun-food-friends-eeec7",
storageBucket: "fun-food-friends-eeec7.appspot.com",
messagingSenderId: "144750278413"
};
firebase.initializeApp(config);
export default firebase;
Fügen Sie vor dem export default firebase Folgendes hinzu
export const provider = new firebase.auth.GoogleAuthProvider();
export const auth = firebase.auth();
Dies exportiert das Auth-Modul von Firebase sowie den Google Auth Provider, damit wir die Google-Authentifizierung für die Anmeldung überall in unserer Anwendung nutzen können.
Jetzt sind wir bereit, mit der Authentifizierung zu beginnen! Gehen wir zu `app.js`. Zuerst importieren wir das auth-Modul und den Google-Auth-Provider, damit wir sie innerhalb unserer App-Komponente verwenden können
Ändern Sie diese Zeile
import firebase from './firebase.js';
zu
import firebase, { auth, provider } from './firebase.js';
Nun, im Konstruktor Ihrer App, beginnen wir damit, einen Platz in unserem anfänglichen Zustand zu schaffen, der alle Informationen unserer angemeldeten Benutzer speichert.
class App extends Component {
constructor() {
super();
this.state = {
currentItem: '',
username: '',
items: [],
user: null // <-- add this line
}
Hier setzen wir den Standardwert von user auf null, da beim erstmaligen Laden der Client noch nicht mit Firebase authentifiziert ist und unsere Anwendung beim erstmaligen Laden so handeln sollte, als ob er nicht angemeldet wäre.
An- und Abmeldebuttons hinzufügen
Fügen wir nun einen Anmelde- und Abmeldebutton zu unserer Render-Komponente hinzu, damit der Benutzer Schaltflächen hat, auf die er klicken kann, um sich in unserer Anwendung anzumelden
<div className="wrapper">
<h1>Fun Food Friends</h1>
{this.state.user ?
<button onClick={this.logout}>Log Out</button>
:
<button onClick={this.login}>Log In</button>
}
</div>
Wenn der Wert von user wahr ist, bedeutet dies, dass der Benutzer derzeit angemeldet ist und den Abmeldebutton sehen sollte. Wenn der Wert von user null ist, bedeutet dies, dass der Benutzer derzeit abgemeldet ist und den Anmeldebutton sehen sollte.
Der onClick jedes dieser Buttons wird auf zwei Funktionen verweisen, die wir gleich in der Komponente selbst erstellen werden: login und logout.
Wir müssen diese Funktionen auch in unserem Konstruktor binden, da wir schließlich this.setState darin aufrufen müssen und wir Zugriff auf this benötigen.
constructor() {
/* ... */
this.login = this.login.bind(this); // <-- add this line
this.logout = this.logout.bind(this); // <-- add this line
}
Die login-Methode, die unsere Authentifizierung mit Firebase handhabt, sieht wie folgt aus
handleChange(e) {
/* ... */
}
logout() {
// we will add the code for this in a moment, but need to add the method now or the bind will throw an error
}
login() {
auth.signInWithPopup(provider)
.then((result) => {
const user = result.user;
this.setState({
user
});
});
}
Hier rufen wir die Methode signInWithPopup aus dem Auth-Modul auf und übergeben unseren provider (denken Sie daran, dass sich dies auf den Google Auth Provider bezieht). Wenn Sie nun auf den „Anmelden“-Button klicken, wird ein Popup ausgelöst, das uns die Option gibt, uns mit einem Google-Konto anzumelden, wie hier

signInWithPopup hat eine Promise-API, die es uns ermöglicht, .then darauf aufzurufen und eine Callback-Funktion zu übergeben. Diese Callback-Funktion erhält ein result-Objekt, das unter anderem eine Eigenschaft namens .user enthält, die alle Informationen über den gerade erfolgreich angemeldeten Benutzer enthält – einschließlich seines Namens und seines Benutzerfotos. Wir speichern dies dann mit setState im Zustand.
Versuchen Sie, sich anzumelden und dann die React DevTools zu überprüfen – Sie werden den Benutzer dort sehen!

Das sind Sie! Dies enthält auch einen Link zu Ihrem Profilbild von Google, was sehr praktisch ist, da es uns ermöglicht, eine Benutzeroberfläche einzubauen, die das Foto des angemeldeten Benutzers enthält.
Die logout-Methode ist unglaublich geradlinig. Nach der Login-Methode in Ihrer Komponente fügen Sie die folgende Methode hinzu
logout() {
auth.signOut()
.then(() => {
this.setState({
user: null
});
});
}
Wir rufen die Methode signOut auf auth auf und entfernen dann mithilfe der Promise-API den Benutzer aus dem Zustand unserer Anwendung. Da this.state.user nun gleich null ist, sieht der Benutzer anstelle des Abmelden-Buttons den Anmelden-Button.
Anmeldung über Seitenaktualisierungen hinweg beibehalten
Momentan vergisst Ihre Anwendung jedes Mal, wenn Sie die Seite aktualisieren, dass Sie bereits angemeldet waren, was etwas enttäuschend ist. Aber Firebase hat einen Event-Listener, onAuthStateChange, der jedes Mal, wenn die App geladen wird, überprüfen kann, ob der Benutzer bereits bei Ihrem letzten Besuch angemeldet war. Wenn ja, können Sie ihn automatisch wieder anmelden.
Wir werden dies in unserem componentDidMount tun, was für solche Nebeneffekte gedacht ist
componentDidMount() {
auth.onAuthStateChanged((user) => {
if (user) {
this.setState({ user });
}
});
// ...
Wenn sich der Benutzer anmeldet, überprüft dies die Firebase-Datenbank, um zu sehen, ob er bereits zuvor authentifiziert war. Wenn ja, setzen wir seine Benutzerdetails wieder in den Zustand.
Aktualisierung der Benutzeroberfläche zur Darstellung der Benutzeranmeldung
Nachdem die Authentifizierungsdetails unserer Benutzer nun erfolgreich im Zustand unserer Anwendung verfolgt und mit unserer Firebase-Datenbank synchronisiert werden, ist nur noch ein Schritt übrig – wir müssen sie mit der Benutzeroberfläche unserer Anwendung verknüpfen.
Dadurch sehen nur angemeldete Benutzer die Potluck-Liste und haben die Möglichkeit, neue Artikel hinzuzufügen. Wenn ein Benutzer angemeldet ist, sehen wir sein Profilbild, sein Name wird automatisch in den Bereich „Artikel hinzufügen“ eingetragen, und er kann nur seine eigenen Potluck-Artikel entfernen.
Ich möchte, dass Sie damit beginnen, das zu löschen, was Sie zuvor nach dem <header> in der render-Methode Ihrer App hatten – es wird einfacher sein, die einzelnen Elemente wieder hinzuzufügen. Ihre App-Komponenten-Render-Methode sollte also so aussehen.
render() {
return (
<div className='app'>
<header>
<div className="wrapper">
<h1>Fun Food Friends</h1>
{this.state.user ?
<button onClick={this.logout}>Logout</button>
:
<button onClick={this.login}>Log In</button>
}
</div>
</header>
</div>
);
}
Jetzt sind wir bereit, mit der Aktualisierung der Benutzeroberfläche zu beginnen.
Zeigen Sie das Foto des Benutzers an, wenn er angemeldet ist, andernfalls fordern Sie den Benutzer zur Anmeldung auf
Hier packen wir unsere Anwendung in ein großes Ternary. Unterhalb Ihrer Kopfzeile
<div className='app'>
<header>
<div className="wrapper">
<h1>Fun Food Friends</h1>
{this.state.user ?
<button onClick={this.logout}>Logout</button>
:
<button onClick={this.login}>Log In</button>
}
</div>
</header>
{this.state.user ?
<div>
<div className='user-profile'>
<img src={this.state.user.photoURL} />
</div>
</div>
:
<div className='wrapper'>
<p>You must be logged in to see the potluck list and submit to it.</p>
</div>
}
</div>
Wenn Sie nun auf „Anmelden“ klicken, sollten Sie dies sehen

Anzeigen des Bereichs „Artikel hinzufügen“ und Vorbelegen mit dem Anmeldenamen oder der E-Mail des angemeldeten Benutzers
<div>
<div className='user-profile'>
<img src={this.state.user.photoURL} />
</div>
<div className='container'>
<section className='add-item'>
<form onSubmit={this.handleSubmit}>
<input type="text" name="username" placeholder="What's your name?" value={this.state.user.displayName || this.state.user.email} />
<input type="text" name="currentItem" placeholder="What are you bringing?" onChange={this.handleChange} value={this.state.currentItem} />
<button>Add Item</button>
</form>
</section>
</div>
</div>
Hier setzen wir den value unseres Benutzernamens-Feldes auf this.state.user.displayName, falls vorhanden (manchmal haben Benutzer keinen Anzeigenamen), und wenn nicht, setzen wir ihn auf this.state.user.email. Dies sperrt die Eingabe und sorgt dafür, dass die Namen oder E-Mails der Benutzer automatisch in das Feld Artikel hinzufügen eingetragen werden.
Wir aktualisieren auch handleSubmit, da wir uns nicht mehr auf handleChange verlassen, um den Namen des Benutzers im Zustand festzulegen, sondern ihn direkt von this.state.user abrufen können
handleSubmit(e) {
// ....
const item = {
title: this.state.currentItem,
user: this.state.user.displayName || this.state.user.email
}
// ....
}
Ihre App sollte nun so aussehen

Anzeigen von Potluck-Artikeln und Ermöglichen, dass der Benutzer nur seine eigenen entfernt
Nun fügen wir unsere Liste von Potluck-Artikeln wieder hinzu. Wir fügen auch eine Prüfung für jeden Artikel hinzu, um zu sehen, ob der Benutzer, der den Artikel mitbringt, mit dem aktuell angemeldeten Benutzer übereinstimmt. Wenn ja, geben wir ihm die Möglichkeit, diesen Artikel zu entfernen. Dies ist bei weitem nicht narrensicher und ich würde mich in einer Produktions-App nicht darauf verlassen, aber es ist ein cooles kleines Extra, das wir unserer App hinzufügen können
<div className='container'>
{/* .. */}
<section className='display-item'>
<div className="wrapper">
<ul>
{this.state.items.map((item) => {
return (
<li key={item.id}>
<h3>{item.title}</h3>
<p>brought by: {item.user}
{item.user === this.state.user.displayName || item.user === this.state.user.email ?
<button onClick={() => this.removeItem(item.id)}>Remove Item</button> : null}
</p>
</li>
)
})}
</ul>
</div>
</section>
</div>
Anstatt den Entfernen-Button für jeden Artikel anzuzeigen, schreiben wir ein kurzes Ternary, das prüft, ob die Person, die einen bestimmten Artikel mitbringt, mit dem aktuell angemeldeten Benutzer übereinstimmt. Wenn es eine Übereinstimmung gibt, stellen wir ihnen einen Button zum Entfernen dieses Artikels zur Verfügung

Hier kann ich Nudelsalat entfernen, da ich ihn zur Potluck-Liste hinzugefügt habe, aber ich kann Kartoffeln nicht entfernen (wer bringt Kartoffeln zu einem Potluck? Meine Schwester, offensichtlich.)
Und das ist alles! Das Hinzufügen von Authentifizierung zu einer neuen (oder bestehenden) Firebase-Anwendung ist ein Kinderspiel. Es ist unglaublich geradlinig, kann mit minimaler Refaktorierung hinzugefügt werden und ermöglicht die Persistenz der Authentifizierung über Seitenaktualisierungen hinweg.
Es ist wichtig zu beachten, dass dies eine triviale Anwendung ist – Sie würden zusätzliche Überprüfungen und Sicherungen hinzufügen wollen, um sensible Informationen zu speichern. Aber für die einfachen Zwecke unserer Anwendung ist es perfekt!
Artikelserie
- Einführung in Firebase und React
- Benutzerauthentifizierung (Sie sind hier!)
Es gab in den letzten Wochen eine interessant hohe Menge an Inhalten rund um die Authentifizierung. Ich beschwere mich nicht, denn Firebase passt genau zu meinen Bedürfnissen. Toller Artikel!
Hey Simon, danke für ein weiteres Follow-up-Tutorial zu React und Firebase! Sie sollten eine mehrteilige Serie oder ein E-Book mit einer detaillierteren komplexen Webanwendung in Betracht ziehen, die Firebase auf vielfältige Weise nutzt. Ich wette, es wird viele interessierte Entwickler geben, sobald die Leute herausfinden, dass Firebase und React der beste Weg sind, um eine skalierbare App zu erstellen.
Viel Glück!
Nur am Rande (und um etwas Tipparbeit zu sparen), Sie können es vermeiden, alle Ihre Methoden im Konstruktor binden zu müssen, indem Sie sie in diesem Stil schreiben…
Hallo Simon.
Dieses Tutorial ist wirklich großartig.
Ich bin relativ neu in JS/React.
Ich habe einige Teile Ihres Tutorials wiederverwendet, um mit React/Firebase herumzuspielen.
Und ich habe zwei Fragen
1/ Gibt es eine Möglichkeit, beim Abmelden die Google-Konto-Autorisierung zu beenden und den Benutzer ein anderes Google-Konto auswählen zu lassen? Ich habe verschiedene Ansätze von Stack Overflow ausprobiert, aber keiner hat für mich funktioniert.
Die Methode firebase.auth().signOut().then(function() {…}); lässt Sie kein anderes Konto wählen. (oder vielleicht habe ich es falsch implementiert)
2/ Ich habe versucht, React Router zu verwenden, um die Komponente, die die Elemente anzeigt, auf ihrer Route zu rendern (im Grunde eine einfache Page-App).
Aber es gab ein Problem. Ich habe die Methode setState der Komponente nicht immer in componentDidUpdate aufgerufen. (wie Sie es in handleSubmit(e) {…} haben).
Aber mit React Router gab es immer einen Fehler in der Konsole, dass ich versuche, setState außerhalb von componentDidMount {}.
Was ist der richtige Ansatz für diese Situation? Ich konnte es nicht zum Laufen bringen…
Vielen Dank.
Mit freundlichen Grüßen.
Peter
Simon, vielen Dank für den Artikel aus der Ukraine ;)
Ich bin Designer, und es ist wunderschön, wenn ich Schritt für Schritt das Backend lernen kann
Das Tutorial ist wirklich gut. Ich habe mich nur gefragt, was wir tun können, um den Benutzer mit anderen Drittanbietern wie Facebook oder mit der eigenen E-Mail und dem Passwort des Benutzers zu authentifizieren.
Schauen Sie sich die Firebase-Authentifizierung an, dort finden Sie Details zu FB-/E-Mail-Authentifizierung und mehr.