1. Обзор
В этой лаборатории вы познакомитесь с основами Firebase для создания интерактивных веб-приложений. Вы создадите приложение для ответа на приглашение на мероприятие и чата с гостевой книгой, используя несколько продуктов Firebase.
Что вы узнаете
- Аутентифицируйте пользователей с помощью Firebase Authentication и FirebaseUI.
- Синхронизируйте данные с помощью Cloud Firestore.
- Напишите правила безопасности Firebase для защиты базы данных.
Что вам понадобится
- Браузер по вашему выбору, например Chrome.
- Доступ к stackblitz.com (учетная запись или вход в систему не требуются).
- Учетная запись Google, например учетная запись Gmail. Мы рекомендуем использовать учетную запись электронной почты, которую вы уже используете для своей учетной записи GitHub. Это позволяет вам использовать расширенные функции StackBlitz.
- Пример кода Codelab. См. следующий шаг, чтобы узнать, как получить код.
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 .
- В консоли Firebase нажмите «Добавить проект» (или «Создать проект» ), затем назовите свой проект Firebase Firebase-Web-Codelab .
- Просмотрите параметры создания проекта. Примите условия Firebase, если будет предложено. На экране Google Analytics нажмите «Не включать», поскольку вы не будете использовать 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), которые помогают уменьшить общий размер веб-страницы с помощью процесса, называемого «встряхиванием дерева». Подробнее о модульных 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 Authentication .
Аутентифицируйте своих пользователей с помощью входа в систему по электронной почте и FirebaseUI.
Вам понадобится кнопка RSVP, которая предложит пользователю войти в систему, используя свой адрес электронной почты. Вы можете сделать это, подключив FirebaseUI к кнопке RSVP. FirebaseUI — это библиотека, которая предоставляет вам предварительно созданный пользовательский интерфейс поверх Firebase Auth.
FirebaseUI требует конфигурации (см. параметры в документации ), которая делает две вещи:
- Сообщает FirebaseUI, что вы хотите использовать метод входа по электронной почте и паролю .
- Обрабатывает обратный вызов для успешного входа в систему и возвращает false, чтобы избежать перенаправления. Вы не хотите, чтобы страница обновлялась, поскольку вы создаете одностраничное веб-приложение.
Добавьте код для инициализации аутентификации FirebaseUI.
- В 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 нажмите кнопку «Ответить», чтобы войти в приложение.
- Для этой лаборатории кода вы можете использовать любой адрес электронной почты, даже поддельный адрес электронной почты, поскольку для этой лаборатории кода вы не настраиваете этап проверки электронной почты.
- Если вы видите сообщение об ошибке с указанием
auth/operation-not-allowed
илиThe given sign-in provider is disabled for this Firebase project
, убедитесь, что вы включили адрес электронной почты/пароль в качестве поставщика входа в консоль Firebase.
- Перейдите на панель аутентификации в консоли Firebase. На вкладке «Пользователи» вы должны увидеть данные учетной записи, которые вы ввели для входа в приложение.
Добавьте состояние аутентификации в пользовательский интерфейс
Затем убедитесь, что пользовательский интерфейс отражает тот факт, что вы вошли в систему.
Вы будете использовать обратный вызов прослушивателя состояния аутентификации Firebase, который получает уведомление при каждом изменении статуса входа пользователя. Если в настоящее время есть вошедший в систему пользователь, ваше приложение заменит кнопку «Ответить» на кнопку «Выход».
- В 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 Authentication предоставляет всем вошедшим в систему пользователям.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. Бонусный шаг: практикуйте то, что вы узнали.
Запишите статус ответа участника
Прямо сейчас ваше приложение просто позволяет людям начать общаться, если они заинтересованы в событии. Кроме того, единственный способ узнать, придет ли кто-то, — это опубликовать это в чате. Давайте организуемся и сообщим людям, сколько людей придет.
Вы добавите переключатель для регистрации людей, желающих посетить мероприятие, а затем подсчитаете, сколько людей придет.
- В 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> <!-- ... -->
Предварительный просмотр приложения
Затем зарегистрируйте прослушиватель нажатий кнопок. Если пользователь нажимает YES , используйте свой 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
, а затем зарегистрируйте ссылку на документ, если будет нажата любая кнопка «Ответить на приглашение». Установите для этой ссылки значение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
отправителя совпадает с идентификатором документа, который он пишет. Вы разрешите всем читать список участников (поскольку в нем нет личных данных), но только создатель сможет его обновлять.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.
Прочитать статус ответа
Теперь, когда вы записали ответы, давайте посмотрим, кто придет, и отразим это в пользовательском интерфейсе.
- В StackBlitz перейдите к файлу
index.html
. - В
description-container
добавьте новый элемент с идентификаторомnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
Затем зарегистрируйте прослушиватель для коллекции attendees
и подсчитайте количество ответов YES :
- В StackBlitz перейдите к файлу
index.js
. - В нижней части функции
main()
добавьте следующий код для прослушивания статуса ответа и подсчета кликов ДА .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
- Облачный пожарный магазин
- Правила безопасности Firebase
Следующие шаги
- Хотите узнать больше о рабочем процессе разработчика Firebase? Ознакомьтесь с кодовой лабораторией эмулятора Firebase, чтобы узнать, как тестировать и запускать ваше приложение полностью локально.
- Хотите узнать больше о других продуктах Firebase? Может быть, вы хотите хранить файлы изображений, загружаемые пользователями? Или отправлять уведомления своим пользователям? Ознакомьтесь с веб-лабораторией кода Firebase , где вы найдете более подробную информацию о многих других веб-продуктах Firebase.
- Хотите узнать больше об Cloud Firestore? Может быть, вы хотите узнать о подколекциях и транзакциях? Посетите веб-лабораторию кода Cloud Firestore , чтобы получить более подробную информацию о Cloud Firestore. Или посмотрите эту серию YouTube, чтобы познакомиться с Cloud Firestore !
Узнать больше
- Сайт Firebase: firebase.google.com.
- Канал Firebase на YouTube
Как все прошло?
Мы будем рады вашим отзывам! Пожалуйста, заполните (очень) короткую форму здесь .