1. Обзор
В этой лабораторной работе вы изучите основы Firebase для создания интерактивных веб-приложений. Вы создадите приложение для RSVP-подписки на мероприятия и чата с гостевой книгой, используя несколько продуктов Firebase.
Чему вы научитесь
- Аутентифицируйте пользователей с помощью Firebase Authentication и FirebaseUI.
- Синхронизируйте данные с помощью Cloud Firestore.
- Напишите правила безопасности Firebase для защиты базы данных.
Что вам понадобится
- Браузер по вашему выбору, например Chrome.
- Доступ к stackblitz.com (учетная запись или регистрация не требуются).
- Учётная запись Google, например, Gmail. Мы рекомендуем использовать ту учётную запись электронной почты, которую вы уже используете для своего аккаунта GitHub. Это позволит вам использовать расширенные функции StackBlitz.
- Пример кода для практического занятия. Чтобы узнать, как получить код, смотрите следующий шаг.
2. Получите стартовый код
В этой лабораторной работе вы создадите приложение с помощью StackBlitz — онлайн-редактора, в который интегрировано несколько рабочих процессов Firebase. Stackblitz не требует установки программного обеспечения или специальной учётной записи StackBlitz.
StackBlitz позволяет вам делиться проектами с другими. Другие пользователи, у которых есть URL вашего проекта StackBlitz, могут видеть ваш код и создавать ответвления, но не могут редактировать ваш проект StackBlitz.
- Перейдите по этому URL-адресу для получения начального кода: https://stackblitz.com/edit/firebase-gtk-web-start
- В верхней части страницы StackBlitz нажмите Fork :
Теперь у вас есть копия начального кода в виде вашего собственного проекта StackBlitz с уникальным именем и уникальным URL-адресом. Все ваши файлы и изменения сохраняются в этом проекте StackBlitz.
3. Редактировать информацию о событии
Исходные материалы для этой практической работы предоставляют некоторую структуру веб-приложения, включая несколько таблиц стилей и несколько HTML-контейнеров. Далее в этой практической работе вы подключите эти контейнеры к Firebase.
Для начала давайте немного познакомимся с интерфейсом StackBlitz.
- В StackBlitz откройте файл
index.html
. - Найдите
event-details-container
иdescription-container
, затем попробуйте отредактировать некоторые сведения о событии.
Пока вы редактируете текст, автоматическая перезагрузка страницы в StackBlitz отображает информацию о новом событии. Круто, правда?
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
Предварительный просмотр вашего приложения должен выглядеть примерно так:
Предварительный просмотр приложения
4. Создайте и настройте проект Firebase.
Отображение информации о мероприятиях — отличный способ привлечь гостей, но простое отображение самих мероприятий никому не нужно. Давайте добавим в это приложение динамическую функциональность. Для этого вам потребуется подключить Firebase к вашему приложению. Чтобы начать работу с Firebase, вам необходимо создать и настроить проект Firebase.
Создать проект Firebase
- Войдите в консоль Firebase, используя свою учетную запись Google.
- Нажмите кнопку, чтобы создать новый проект, а затем введите имя проекта (например,
Firebase-Web-Codelab
). - Нажмите «Продолжить» .
- При появлении соответствующего запроса ознакомьтесь с условиями Firebase и примите их, а затем нажмите кнопку «Продолжить» .
- (Необязательно) Включите помощь ИИ в консоли Firebase (так называемая «Gemini в Firebase»).
- Для этой лабораторной работы вам не понадобится Google Analytics, поэтому отключите опцию Google Analytics.
- Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .
Дополнительную информацию о проектах Firebase см. в разделе Понимание проектов Firebase .
Включите и настройте продукты Firebase в консоли
Приложение, которое вы создаете, использует несколько продуктов Firebase, доступных для веб-приложений:
- Аутентификация Firebase и пользовательский интерфейс Firebase позволяют пользователям легко входить в ваше приложение.
- Cloud Firestore для сохранения структурированных данных в облаке и мгновенного получения уведомлений об изменении данных.
- Правила безопасности Firebase для защиты вашей базы данных.
Некоторые из этих продуктов требуют специальной настройки или должны быть включены с помощью консоли Firebase.
Включить вход по электронной почте для аутентификации Firebase
Чтобы разрешить пользователям входить в веб-приложение, для этой лабораторной работы вы будете использовать метод входа с использованием электронной почты и пароля :
- На левой панели консоли Firebase нажмите «Сборка» > «Аутентификация» . Затем нажмите « Начать» . Теперь вы находитесь на панели управления аутентификацией, где можете видеть зарегистрированных пользователей, настраивать поставщиков услуг входа и управлять параметрами.
- Выберите вкладку «Способ входа» (или нажмите здесь, чтобы перейти непосредственно на вкладку).
- Нажмите «Электронная почта/Пароль» в параметрах поставщика, переведите переключатель в положение «Включить» , а затем нажмите «Сохранить» .
Настройка Cloud Firestore
Веб-приложение использует Cloud Firestore для сохранения сообщений чата и получения новых сообщений чата.
Вот как настроить Cloud Firestore в вашем проекте Firebase:
- На левой панели консоли Firebase разверните пункт «Сборка» , а затем выберите «База данных Firestore» .
- Нажмите Создать базу данных .
- Оставьте идентификатор базы данных равным
(default)
. - Выберите местоположение вашей базы данных, затем нажмите «Далее» .
Для настоящего приложения вам нужно выбрать местоположение, близкое к вашим пользователям. - Нажмите «Начать в тестовом режиме» . Ознакомьтесь с отказом от ответственности о правилах безопасности.
Далее в этой лабораторной работе вы добавите правила безопасности для защиты своих данных. Не распространяйте и не публикуйте приложение, не добавив правила безопасности для своей базы данных. - Нажмите «Создать» .
5. Добавьте и настройте Firebase
Теперь, когда вы создали проект Firebase и включили некоторые службы, вам нужно указать коду, что вы хотите использовать Firebase, а также какой проект Firebase использовать.
Добавьте библиотеки Firebase
Чтобы ваше приложение использовало Firebase, необходимо добавить библиотеки Firebase. Это можно сделать несколькими способами, как описано в документации Firebase . Например, вы можете добавить библиотеки из CDN Google или установить их локально с помощью npm, а затем упаковать в своё приложение, если вы используете Browserify.
StackBlitz обеспечивает автоматическую сборку, поэтому вы можете добавлять библиотеки Firebase с помощью операторов импорта. Вы будете использовать модульные версии библиотек (v9), которые помогают уменьшить общий размер веб-страницы благодаря процессу, называемому «tree shake». Подробнее о модульных SDK можно узнать в документации .
Для создания этого приложения используются библиотеки Firebase Authentication, FirebaseUI и Cloud Firestore. В этой лабораторной работе следующие операторы импорта уже включены в начало файла index.js
, и мы будем импортировать дополнительные методы из каждой библиотеки Firebase по мере выполнения:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
Добавьте веб-приложение Firebase в свой проект Firebase
- Вернувшись в консоль Firebase, перейдите на страницу обзора вашего проекта, нажав «Обзор проекта» в левом верхнем углу.
- В центре страницы обзора вашего проекта нажмите на значок Интернета.
для создания нового веб-приложения Firebase.
- Зарегистрируйте приложение под именем Web App .
- Для этой практической работы НЕ устанавливайте флажок « Также настроить хостинг Firebase для этого приложения» . Пока что вы будете использовать панель предварительного просмотра StackBlitz.
- Нажмите «Зарегистрировать приложение» .
- Скопируйте объект конфигурации Firebase в буфер обмена.
- Нажмите «Продолжить», чтобы перейти в консоль . Добавьте объект конфигурации Firebase в свое приложение:
- Вернитесь в StackBlitz и перейдите к файлу
index.js
. - Найдите строку комментария
Add Firebase project configuration object here
, затем вставьте фрагмент конфигурации прямо под комментарием. - Добавьте вызов функции
initializeApp
для настройки Firebase с использованием уникальной конфигурации вашего проекта Firebase.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.firebasestorage.app", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. Добавьте вход пользователя (RSVP)
Теперь, когда вы добавили Firebase в приложение, вы можете настроить кнопку RSVP, которая регистрирует людей, использующих аутентификацию Firebase .
Аутентифицируйте своих пользователей с помощью входа по электронной почте и FirebaseUI
Вам понадобится кнопка RSVP, которая предложит пользователю войти, указав свой адрес электронной почты. Это можно сделать, подключив FirebaseUI к кнопке RSVP. FirebaseUI — это библиотека, предоставляющая готовый пользовательский интерфейс на основе Firebase Auth.
Для FirebaseUI требуется конфигурация (см. параметры в документации ), которая выполняет две функции:
- Сообщает FirebaseUI, что вы хотите использовать метод входа по электронной почте/паролю .
- Обрабатывает обратный вызов при успешном входе и возвращает значение false, чтобы избежать перенаправления. Вы не хотите, чтобы страница обновлялась, поскольку создаёте одностраничное веб-приложение.
Добавьте код для инициализации FirebaseUI Auth.
- В StackBlitz перейдите к файлу
index.js
. - Вверху найдите оператор импорта
firebase/auth
, затем добавьтеgetAuth
иEmailAuthProvider
, вот так:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- Сохраните ссылку на объект аутентификации сразу после
initializeApp
, например так:initializeApp(firebaseConfig); auth = getAuth();
- Обратите внимание, что конфигурация FirebaseUI уже присутствует в стартовом коде. Она настроена на использование провайдера аутентификации по электронной почте.
- В нижней части функции
main()
вindex.js
добавьте оператор инициализации FirebaseUI, например:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
Добавьте кнопку RSVP в HTML-код
- В StackBlitz перейдите к файлу
index.html
. - Добавьте HTML-код для кнопки RSVP внутри
event-details-container
как показано в примере ниже.
Будьте внимательны и используйте те же значенияid
, что показаны ниже, поскольку для этой кодовой работы уже есть хуки для этих конкретных идентификаторов в файлеindex.js
.
Обратите внимание, что в файлеindex.html
есть контейнер с идентификаторомfirebaseui-auth-container
. Этот идентификатор вы передадите в FirebaseUI для хранения данных вашего входа. Предварительный просмотр приложения<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- Настройте прослушиватель на кнопке RSVP и вызовите функцию запуска FirebaseUI. Это сообщит FirebaseUI, что вы хотите увидеть окно входа.
Добавьте следующий код в конец функцииmain()
вindex.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
Тестовый вход в приложение
- В окне предварительного просмотра StackBlitz нажмите кнопку RSVP, чтобы войти в приложение.
- Для этой лабораторной работы вы можете использовать любой адрес электронной почты, даже поддельный, поскольку для этой лабораторной работы вам не нужно настраивать этап проверки адреса электронной почты.
- Если вы видите сообщение об ошибке
auth/operation-not-allowed
илиThe given sign-in provider is disabled for this Firebase project
, убедитесь, что вы включили электронную почту/пароль в качестве поставщика входа в консоли Firebase.
- Перейдите на панель управления аутентификацией в консоли Firebase. На вкладке «Пользователи» вы увидите данные учётной записи, которые вы ввели для входа в приложение.
Добавить состояние аутентификации в пользовательский интерфейс
Затем убедитесь, что пользовательский интерфейс отображает тот факт, что вы вошли в систему.
Вы будете использовать обратный вызов прослушивателя состояния аутентификации Firebase, который будет получать уведомления при каждом изменении статуса входа пользователя. Если в системе есть вошедший пользователь, ваше приложение заменит кнопку «RSVP» на кнопку «Выйти».
- В StackBlitz перейдите к файлу
index.js
. - Вверху найдите оператор импорта
firebase/auth
, затем добавьтеsignOut
иonAuthStateChanged
, вот так:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore';
- Добавьте следующий код в конец функции
main()
:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main();
- В прослушивателе кнопки проверьте наличие текущего пользователя и выйдите из системы. Для этого замените текущий
startRsvpButton.addEventListener
следующим:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
Теперь кнопка в вашем приложении должна показывать LOGOUT (ВЫХОД) , а при нажатии она должна снова переключаться на RSVP .
Предварительный просмотр приложения
7. Напишите сообщения в Cloud Firestore
Знать, что пользователи придут, — это здорово, но давайте предложим гостям что-то ещё в приложении. Что, если бы они могли оставлять сообщения в гостевой книге? Они могли бы рассказать, почему они рады приехать, или с кем надеются встретиться.
Для хранения сообщений чата, которые пользователи пишут в приложении, вы будете использовать Cloud Firestore .
Модель данных
Cloud Firestore — это база данных NoSQL, в которой данные делятся на коллекции, документы, поля и подколлекции. Каждое сообщение чата будет храниться как документ в коллекции верхнего уровня, называемой guestbook
.
Добавить сообщения в Firestore
В этом разделе вы добавите функционал, позволяющий пользователям добавлять новые сообщения в базу данных. Сначала вы добавите HTML-код для элементов пользовательского интерфейса (поля сообщения и кнопки отправки), а затем — код, подключающий эти элементы к базе данных.
Чтобы добавить элементы пользовательского интерфейса поля сообщения и кнопку отправки:
- В StackBlitz перейдите к файлу
index.html
. - Найдите
guestbook-container
, затем добавьте следующий HTML-код, чтобы создать форму с полем ввода сообщения и кнопкой отправки.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
Предварительный просмотр приложения
Нажатие пользователем кнопки «ОТПРАВИТЬ» активирует приведённый ниже фрагмент кода. Он добавляет содержимое поля ввода сообщения в коллекцию guestbook
базы данных. В частности, метод addDoc
добавляет содержимое сообщения в новый документ (с автоматически сгенерированным идентификатором) в коллекцию guestbook
.
- В StackBlitz перейдите к файлу
index.js
. - Вверху найдите оператор импорта
firebase/firestore
, затем добавьтеgetFirestore
,addDoc
иcollection
, вот так:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore';
- Теперь сохраним ссылку на объект
db
Firestore сразу послеinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- Внизу функции
main()
добавьте следующий код.
Обратите внимание, чтоauth.currentUser.uid
— это ссылка на автоматически сгенерированный уникальный идентификатор, который аутентификация Firebase присваивает всем вошедшим в систему пользователям.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
Показывать гостевую книгу только зарегистрированным пользователям
Вы не хотите, чтобы чат гостей мог видеть кто угодно . Один из способов защитить чат — разрешить просмотр гостевой книги только зарегистрированным пользователям. Тем не менее, для ваших собственных приложений вам также потребуется защитить базу данных с помощью правил безопасности Firebase . (Подробнее о правилах безопасности см. далее в этом практическом занятии.)
- В StackBlitz перейдите к файлу
index.js
. - Отредактируйте прослушиватель
onAuthStateChanged
, чтобы скрыть и отобразить гостевую книгу.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
Тестовая отправка сообщений
- Убедитесь, что вы вошли в приложение.
- Введите сообщение, например «Привет!», затем нажмите ОТПРАВИТЬ .
Это действие записывает сообщение в базу данных Cloud Firestore. Однако вы пока не увидите сообщение в своём веб-приложении, поскольку вам ещё нужно реализовать извлечение данных. Это мы сделаем далее.
Но вы можете увидеть новое добавленное сообщение в консоли Firebase.
В консоли Firebase, на панели управления базой данных Firestore , вы увидите коллекцию guestbook
с вашим новым сообщением. Если вы продолжите отправлять сообщения, ваша коллекция гостевых книг будет содержать много документов, например:
Консоль Firebase
8. Прочитать сообщения
Синхронизировать сообщения
Замечательно, что гости могут писать сообщения в базу данных, но пока не могут видеть их в приложении.
Для отображения сообщений вам необходимо добавить прослушиватели, которые срабатывают при изменении данных, а затем создать элемент пользовательского интерфейса, отображающий новые сообщения.
Вам нужно добавить код, который отслеживает новые сообщения из приложения. Сначала добавьте в HTML-код раздел для отображения сообщений:
- В StackBlitz перейдите к файлу
index.html
. - В
guestbook-container
добавьте новый раздел с идентификаторомguestbook
.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
Далее зарегистрируем прослушиватель, который отслеживает изменения данных:
- В StackBlitz перейдите к файлу
index.js
. - Вверху найдите оператор импорта
firebase/firestore
, затем добавьтеquery
,orderBy
иonSnapshot
, вот так:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- В конце функции
main()
добавьте следующий код для перебора всех документов (сообщений гостевой книги) в базе данных. Чтобы узнать больше о том, что происходит в этом коде, ознакомьтесь с информацией под фрагментом.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
Для прослушивания сообщений в базе данных вы создали запрос к определённой коллекции с помощью функции collection
. Приведённый выше код прослушивает изменения в коллекции guestbook
, где хранятся сообщения чата. Сообщения также сортируются по дате с помощью orderBy('timestamp', 'desc')
для отображения самых новых сообщений вверху.
Функция onSnapshot
принимает два параметра: используемый запрос и функцию обратного вызова. Функция обратного вызова срабатывает при любых изменениях в документах, соответствующих запросу. Это может произойти при удалении, изменении или добавлении сообщения. Подробнее см. в документации Cloud Firestore .
Тестовая синхронизация сообщений
Cloud Firestore автоматически и мгновенно синхронизирует данные с клиентами, подписанными на базу данных.
- Сообщения, созданные ранее в базе данных, должны отображаться в приложении. Не стесняйтесь писать новые сообщения — они должны появляться мгновенно.
- Если вы открываете свое рабочее пространство в нескольких окнах или вкладках, сообщения будут синхронизироваться в реальном времени между вкладками.
- (Необязательно) Вы можете попробовать вручную удалить, изменить или добавить новые сообщения непосредственно в разделе «База данных» консоли Firebase; любые изменения должны отобразиться в пользовательском интерфейсе.
Поздравляем! Вы читаете документы Cloud Firestore в своём приложении!
Предварительный просмотр приложения
9. Установите основные правила безопасности
Изначально Cloud Firestore настроен на использование тестового режима, то есть ваша база данных открыта для чтения и записи. Однако тестовый режим следует использовать только на самых ранних этапах разработки. Рекомендуется настраивать правила безопасности для базы данных по мере разработки приложения. Безопасность должна быть неотъемлемой частью структуры и поведения вашего приложения.
Правила безопасности позволяют контролировать доступ к документам и коллекциям в базе данных. Гибкий синтаксис правил позволяет создавать правила, которые охватывают любые операции — от всех записей во всей базе данных до операций с конкретным документом.
Вы можете написать правила безопасности для Cloud Firestore в консоли Firebase:
- В разделе «Сборка» консоли Firebase нажмите «База данных Firestore» , затем выберите вкладку «Правила» (или нажмите здесь, чтобы перейти непосредственно на вкладку «Правила» ).
- Вы должны увидеть следующие правила безопасности по умолчанию с ограничением по времени публичного доступа через пару недель, начиная с сегодняшнего дня.
Определить коллекции
Сначала определите коллекции, в которые приложение записывает данные.
- Удалите существующее предложение
match /{document=**}
, чтобы ваши правила выглядели так:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- В
match /databases/{database}/documents
определите коллекцию, которую вы хотите защитить:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
Добавить правила безопасности
Поскольку вы использовали UID аутентификации в качестве поля в каждом документе гостевой книги, вы можете получить UID аутентификации и убедиться, что любой, кто пытается записать в документ, имеет соответствующий UID аутентификации.
- Добавьте правила чтения и записи в ваш набор правил, как показано ниже:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } }
- Нажмите «Опубликовать» , чтобы применить новые правила. Теперь читать сообщения в гостевой книге (любые!) смогут только зарегистрированные пользователи, но создавать сообщения можно только с помощью своего идентификатора пользователя. Мы также не разрешаем редактировать и удалять сообщения.
Добавить правила проверки
- Добавьте проверку данных, чтобы убедиться, что все ожидаемые поля присутствуют в документе:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } }
- Нажмите «Опубликовать» , чтобы внедрить новые правила.
Сбросить слушателей
Поскольку ваше приложение теперь позволяет входить в систему только аутентифицированным пользователям, вам следует переместить запрос firestore
гостевой книги в прослушиватель аутентификации. В противном случае возникнут ошибки доступа, и приложение будет отключено при выходе пользователя из системы.
- В StackBlitz перейдите к файлу
index.js
. - Добавьте прослушиватель
onSnapshot
коллекции гостевых книг в новую функциюsubscribeGuestbook
. Также присвойте результаты функцииonSnapshot
переменнойguestbookListener
.
Прослушиватель FirestoreonSnapshot
возвращает функцию отмены подписки, которую вы сможете использовать для отмены прослушивателя снимков позже.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); }
- Добавьте новую функцию под названием
unsubscribeGuestbook
. Проверьте, не равна ли переменнаяguestbookListener
нулю, а затем вызовите функцию, чтобы отменить прослушивание.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
Наконец, добавьте новые функции в обратный вызов onAuthStateChanged
.
- Добавьте
subscribeGuestbook()
в конецif (user)
. - Добавьте
unsubscribeGuestbook()
в конец оператораelse
.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. Бонусный шаг: практикуйте то, что вы узнали
Запишите статус RSVP участника
Сейчас ваше приложение позволяет людям начать чат, если им интересно мероприятие. Кроме того, единственный способ узнать, придёт ли кто-то, — это написать об этом в чате. Давайте организуемся и сообщим людям, сколько человек придёт.
Вы добавите переключатель для регистрации людей, желающих посетить мероприятие, а затем соберете количество пришедших людей.
- В StackBlitz перейдите к файлу
index.html
. - В
guestbook-container
добавьте набор кнопок ДА и НЕТ , например:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
Предварительный просмотр приложения
Затем зарегистрируйте прослушиватель нажатий кнопок. Если пользователь нажмёт «ДА» , используйте его UID аутентификации для сохранения ответа в базе данных.
- В StackBlitz перейдите к файлу
index.js
. - Вверху найдите оператор импорта
firebase/firestore
, затем добавьтеdoc
,setDoc
иwhere
, вот так:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore';
- В нижней части функции
main()
добавьте следующий код для прослушивания статуса RSVP:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main();
- Затем создайте новую коллекцию с именем
attendees
и зарегистрируйте ссылку на документ при нажатии любой из кнопок RSVP. Установите для этой ссылки значениеtrue
илиfalse
в зависимости от того, какая кнопка нажата.
Во-первых, дляrsvpYes
: Затем то же самое для// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };
rsvpNo
, но со значениемfalse
:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
Обновите свои правила безопасности
Поскольку у вас уже установлены некоторые правила, новые данные, которые вы добавляете с помощью кнопок, будут отклонены.
Разрешить дополнения к коллекции attendees
Вам необходимо обновить правила, чтобы разрешить добавление в коллекцию attendees
.
- Что касается коллекции
attendees
, поскольку вы использовали UID аутентификации в качестве имени документа, вы можете получить её и убедиться, чтоuid
отправителя совпадает с UID создаваемого документа. Вы разрешите всем читать список участников (поскольку там нет личных данных), но обновлять его сможет только создатель.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } }
- Нажмите «Опубликовать» , чтобы внедрить новые правила.
Добавить правила проверки
- Добавьте несколько правил проверки данных, чтобы убедиться, что все ожидаемые поля присутствуют в документе:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } }
- Не забудьте нажать кнопку «Опубликовать» , чтобы внедрить свои правила!
(Необязательно) Теперь вы можете просматривать результаты нажатия кнопок. Перейдите на панель управления Cloud Firestore в консоли Firebase.
Прочитать статус RSVP
Теперь, когда вы записали ответы, давайте посмотрим, кто придет, и отразим это в пользовательском интерфейсе.
- В StackBlitz перейдите к файлу
index.html
. - В
description-container
добавьте новый элемент с идентификаторомnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
Далее регистрируем слушателя для сбора attendees
и подсчитываем количество ответов «ДА» :
- В StackBlitz перейдите к файлу
index.js
. - В нижней части функции
main()
добавьте следующий код для прослушивания статуса RSVP и подсчета кликов «ДА» .async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
Наконец, давайте выделим кнопку, соответствующую текущему статусу.
- Создайте функцию, которая проверяет, есть ли запись текущего UID аутентификации в коллекции
attendees
, затем задайте классу кнопки значениеclicked
.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); }
- Также давайте создадим функцию для отмены подписки. Она будет срабатывать при выходе пользователя из системы.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; }
- Вызовите функции из прослушивателя аутентификации.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subscribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } });
- Попробуйте войти в систему как несколько пользователей и увидите, как с каждым нажатием кнопки «ДА» счетчик увеличивается.
Предварительный просмотр приложения
11. Поздравляем!
Вы использовали Firebase для создания интерактивного веб-приложения, работающего в режиме реального времени!
Что мы рассмотрели
- Аутентификация Firebase
- FirebaseUI
- Cloud Firestore
- Правила безопасности Firebase
Следующие шаги
- Хотите узнать больше о рабочем процессе разработчика Firebase? Ознакомьтесь с практической частью по эмулятору Firebase, чтобы узнать, как протестировать и запустить приложение полностью локально.
- Хотите узнать больше о других продуктах Firebase? Возможно, вам нужно хранить изображения, загружаемые пользователями? Или отправлять уведомления пользователям? Ознакомьтесь с практической работой по веб-версии Firebase, где подробно рассматриваются многие другие продукты Firebase для веб-версии.
- Хотите узнать больше о Cloud Firestore? Возможно, вам интересно узнать о вложенных коллекциях и транзакциях? Посетите веб-сайт Cloud Firestore, где вы найдете практикум, подробно рассказывающий об Cloud Firestore. Или посмотрите эту серию видео на YouTube, чтобы узнать больше об Cloud Firestore !
Узнать больше
- Сайт Firebase: firebase.google.com
- Канал Firebase на YouTube
Как всё прошло?
Мы будем рады вашим отзывам! Пожалуйста, заполните (очень) короткую форму здесь .