Познакомьтесь с Firebase для Интернета

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.

  1. Чтобы получить начальный код, перейдите по этой ссылке: https://stackblitz.com/edit/firebase-gtk-web-start
  2. В верхней части страницы StackBlitz нажмите кнопку «Fork» :

скриншот этого шага

Теперь у вас есть копия исходного кода в виде собственного проекта StackBlitz, который имеет уникальное имя и уникальный URL-адрес. Все ваши файлы и изменения сохраняются в этом проекте StackBlitz.

3. Редактирование информации о событии

Исходные материалы для этого практического занятия предоставляют некоторую структуру для веб-приложения, включая несколько таблиц стилей и пару HTML-контейнеров для приложения. Позже в этом практическом занятии вы подключите эти контейнеры к Firebase.

Для начала давайте немного познакомимся с интерфейсом StackBlitz.

  1. В StackBlitz откройте файл index.html .
  2. Найдите 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.

  1. Войдите в консоль Firebase, используя свою учетную запись Google.
  2. Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например, Firebase-Web-Codelab ).
  3. Нажмите «Продолжить» .
  4. Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
  5. (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
  6. Для этого практического занятия вам не понадобится Google Analytics, поэтому отключите эту опцию.
  7. Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .

Чтобы узнать больше о проектах Firebase, см. раздел «Понимание проектов Firebase» .

Включение и настройка продуктов Firebase в консоли.

В разрабатываемом вами приложении используется несколько продуктов Firebase, доступных для веб-приложений:

  • Firebase Authentication и Firebase UI позволяют пользователям легко входить в ваше приложение.
  • Cloud Firestore позволяет сохранять структурированные данные в облаке и получать мгновенные уведомления об изменениях данных.
  • Правила безопасности Firebase для защиты вашей базы данных.

Для некоторых из этих продуктов требуется специальная настройка или их включение через консоль Firebase.

Включите вход по электронной почте для аутентификации Firebase.

Для авторизации пользователей в веб-приложении в этом практическом задании будет использоваться метод входа по электронной почте и паролю :

  1. В левой панели консоли Firebase нажмите Build > Authentication . Затем нажмите Get Started . Теперь вы находитесь на панели управления аутентификацией, где можете видеть зарегистрированных пользователей, настраивать поставщиков авторизации и управлять параметрами.

    скриншот этого шага

  2. Выберите вкладку «Способ входа» (или нажмите здесь, чтобы перейти непосредственно к этой вкладке).

    скриншот этого шага

  3. В параметрах поставщика услуг выберите пункт «Электронная почта/Пароль» , переведите переключатель в положение «Включить» , а затем нажмите «Сохранить» .

    скриншот этого шага

Настройка Cloud Firestore

Веб-приложение использует Cloud Firestore для сохранения сообщений чата и получения новых сообщений.

Вот как настроить Cloud Firestore в вашем проекте Firebase:

  1. В левой панели консоли Firebase разверните раздел «Сборка» , а затем выберите базу данных Firestore .
  2. Нажмите «Создать базу данных» .
  3. Оставьте значение параметра " Идентификатор базы данных" равным (default) .
  4. Выберите местоположение для вашей базы данных, затем нажмите «Далее» .
    Для создания настоящего приложения вам следует выбрать местоположение, расположенное недалеко от ваших пользователей.
  5. Нажмите «Пуск» в тестовом режиме . Ознакомьтесь с отказом от ответственности в отношении правил безопасности.
    В дальнейшем в этом практическом занятии вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не предоставляйте публичный доступ к приложению, не добавив правила безопасности для вашей базы данных.
  6. Нажмите «Создать» .

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.

  1. Вернувшись в консоль Firebase, перейдите на страницу обзора вашего проекта, нажав кнопку «Обзор проекта» в верхнем левом углу.
  2. В центре страницы обзора вашего проекта нажмите на значок веб-страницы. значок веб-приложения создать новое веб-приложение Firebase.

    скриншот этого шага

  3. Зарегистрируйте приложение, присвоив ему псевдоним Web App .
  4. Для этого практического задания НЕ ставьте галочку рядом с пунктом «Также настройте Firebase Hosting для этого приложения» . Пока что вы будете использовать панель предварительного просмотра StackBlitz.
  5. Нажмите «Зарегистрировать приложение» .

    скриншот этого шага

  6. Скопируйте объект конфигурации Firebase в буфер обмена.

    скриншот этого шага

  7. Нажмите «Продолжить» в консоли . Добавьте объект конфигурации Firebase в ваше приложение:
  8. Вернитесь в StackBlitz и перейдите к файлу index.js .
  9. Найдите строку комментария Add Firebase project configuration object here , затем вставьте свой фрагмент конфигурации сразу под комментарием.
  10. Добавьте вызов функции 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.

  1. В StackBlitz перейдите к файлу index.js .
  2. В самом верху найдите оператор импорта 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';
    
  3. Сохраните ссылку на объект аутентификации сразу после вызова initializeApp , следующим образом:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. Обратите внимание, что конфигурация FirebaseUI уже предоставлена ​​в исходном коде. Она уже настроена для использования поставщика аутентификации по электронной почте.
  5. В конце функции main() в index.js добавьте оператор инициализации FirebaseUI следующим образом:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

Добавьте кнопку подтверждения участия (RSVP) в HTML-код.

  1. В StackBlitz перейдите к файлу index.html .
  2. Добавьте 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>
    <!-- ... -->
    
    Предварительный просмотр приложения

    скриншот этого шага

  3. Настройте обработчик событий для кнопки RSVP и вызовите функцию запуска FirebaseUI. Это сообщит FirebaseUI, что вы хотите отобразить окно входа в систему.

    Добавьте следующий код в конец функции main() в index.js :
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

Проверка входа в приложение

  1. В окне предварительного просмотра StackBlitz нажмите кнопку RSVP, чтобы войти в приложение.
    • Для этого практического задания вы можете использовать любой адрес электронной почты, даже вымышленный, поскольку в нем не требуется настраивать этап подтверждения адреса электронной почты.
    • Если вы видите сообщение об ошибке типа auth/operation-not-allowed или The given sign-in provider is disabled for this Firebase project , убедитесь, что вы включили электронную почту/пароль в качестве поставщика авторизации в консоли Firebase.
    Предварительный просмотр приложения

    скриншот этого шага

  2. Перейдите на панель управления «Аутентификация» в консоли Firebase. На вкладке «Пользователи» вы увидите информацию об учетной записи, которую вы ввели для входа в приложение.

    скриншот этого шага

Добавить состояние аутентификации в пользовательский интерфейс

Далее убедитесь, что пользовательский интерфейс отображает тот факт, что вы вошли в систему.

Вы будете использовать функцию обратного вызова прослушивателя состояния Firebase Authentication, которая получает уведомления всякий раз, когда изменяется статус авторизации пользователя. Если в данный момент авторизован пользователь, ваше приложение заменит кнопку «RSVP» на кнопку «Выход».

  1. В StackBlitz перейдите к файлу index.js .
  2. В самом верху найдите оператор импорта 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';
    
  3. Добавьте следующий код в конец функции main() :
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. В обработчике события кнопки проверьте, есть ли текущий пользователь, и выведите его из системы. Для этого замените текущий метод 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);
      }
    });
    

Теперь кнопка в вашем приложении должна отображать «ВЫХОД» , а при нажатии она должна снова смениться на «ПОДТВЕРЖДЕНИЕ УЧАСТИЯ» .

Предварительный просмотр приложения

скриншот этого шага

7. Запись сообщений в Cloud Firestore.

Знать, что пользователи придут, — это здорово, но давайте предложим гостям что-нибудь еще в приложении. Что если бы они могли оставлять сообщения в гостевой книге? Они могли бы рассказать, почему они рады прийти или с кем надеются встретиться.

Для хранения сообщений чата, которые пользователи пишут в приложении, вы будете использовать Cloud Firestore .

модель данных

Cloud Firestore — это база данных NoSQL, данные в которой разделены на коллекции, документы, поля и подколлекции. Каждое сообщение чата будет храниться как документ в коллекции верхнего уровня под названием guestbook .

Графическое изображение модели данных Firestore, демонстрирующее коллекцию гостевых книг с несколькими документами сообщений.

Добавить сообщения в Firestore

В этом разделе вы добавите функциональность для записи пользователями новых сообщений в базу данных. Сначала вы добавите HTML-код для элементов пользовательского интерфейса (поле ввода сообщения и кнопка отправки). Затем вы добавите код, который свяжет эти элементы с базой данных.

Чтобы добавить элементы пользовательского интерфейса в поле для сообщения и кнопку отправки:

  1. В StackBlitz перейдите к файлу index.html .
  2. Найдите элемент 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 .

  1. В StackBlitz перейдите к файлу index.js .
  2. В самом верху найдите оператор импорта 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';
    
  3. Теперь мы сохраним ссылку на объект db Firestore сразу после initializeApp :
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. В конце функции 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 . (Более подробная информация о правилах безопасности приведена далее в практическом руководстве.)

  1. В StackBlitz перейдите к файлу index.js .
  2. Отредактируйте обработчик события 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';
      }
    });
    

Проверка отправки сообщений

  1. Убедитесь, что вы вошли в приложение.
  2. Введите сообщение, например, "Привет!", затем нажмите "Отправить ".

Это действие записывает сообщение в вашу базу данных Cloud Firestore. Однако вы пока не увидите это сообщение в своем веб-приложении, поскольку вам еще нужно реализовать получение данных. Вы сделаете это позже.

Но вы можете увидеть недавно добавленное сообщение в консоли Firebase.

В консоли Firebase, на панели управления базой данных Firestore , вы должны увидеть коллекцию guestbook с вашим недавно добавленным сообщением. Если вы продолжите отправлять сообщения, ваша коллекция гостевой книги будет содержать множество документов, например, таких:

Консоль Firebase

скриншот этого шага

8. Читайте сообщения

Синхронизация сообщений

Замечательно, что гости могут оставлять сообщения в базе данных, но пока они не могут их увидеть в приложении.

Для отображения сообщений вам потребуется добавить обработчики событий, которые срабатывают при изменении данных, а затем создать элемент пользовательского интерфейса, отображающий новые сообщения.

Вам нужно добавить код, который будет отслеживать новые сообщения, добавленные приложением. Сначала добавьте раздел в HTML-код для отображения сообщений:

  1. В StackBlitz перейдите к файлу index.html .
  2. В guestbook-container добавьте новый раздел с идентификатором guestbook .
    <!-- ... -->
    
      <section id="guestbook-container">
       <h2>Discussion</h2>
    
       <form><!-- ... --></form>
    
       <section id="guestbook"></section>
    
     </section>
    
    <!-- ... -->
    

Далее зарегистрируйте слушатель, который будет отслеживать изменения, внесенные в данные:

  1. В StackBlitz перейдите к файлу index.js .
  2. В самом верху найдите оператор импорта firebase/firestore , затем добавьте query , orderBy и onSnapshot следующим образом:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. В конце функции 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 на использование тестового режима, что означает, что ваша база данных открыта для чтения и записи. Однако тестовый режим следует использовать только на самых ранних этапах разработки. В качестве лучшей практики следует настраивать правила безопасности для вашей базы данных по мере разработки приложения. Безопасность должна быть неотъемлемой частью структуры и поведения вашего приложения.

Правила безопасности позволяют контролировать доступ к документам и коллекциям в вашей базе данных. Гибкий синтаксис правил позволяет создавать правила, соответствующие чему угодно — от всех операций записи во всю базу данных до операций над конкретным документом.

В консоли Firebase можно создавать правила безопасности для Cloud Firestore:

  1. В разделе «Сборка» консоли Firebase щелкните «База данных Firestore» , затем выберите вкладку «Правила» (или щелкните здесь, чтобы перейти непосредственно на вкладку «Правила» ).
  2. Вы должны увидеть следующие правила безопасности по умолчанию, с ограничением по времени доступа для публичного использования в течение нескольких недель с сегодняшнего дня.

скриншот этого шага

Идентифицировать коллекции

Сначала определите коллекции, в которые приложение записывает данные.

  1. Удалите существующее условие match /{document=**} , чтобы ваши правила выглядели следующим образом:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
      }
    }
    
  2. В 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 аутентификации.

  1. Добавьте правила чтения и записи в свой набор правил, как показано ниже:
    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;
        }
      }
    }
    
  2. Нажмите «Опубликовать» , чтобы применить новые правила. Теперь в гостевой книге только авторизованные пользователи могут читать сообщения (любые сообщения!), но вы можете создавать сообщения только с помощью своего идентификатора пользователя. Мы также не разрешаем редактировать или удалять сообщения.

Добавить правила проверки

  1. Добавьте проверку данных, чтобы убедиться, что в документе присутствуют все ожидаемые поля:
    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;
        }
      }
    }
    
  2. Нажмите «Опубликовать» , чтобы применить новые правила.

Сбросить слушатели

Поскольку теперь ваше приложение разрешает вход только авторизованным пользователям, вам следует переместить запрос гостевой книги firestore внутрь обработчика аутентификации. В противном случае возникнут ошибки доступа, и приложение будет отключено при выходе пользователя из системы.

  1. В StackBlitz перейдите к файлу index.js .
  2. Вынесите обработчик события onSnapshot для коллекции гостевых книг в новую функцию с именем subscribeGuestbook . Также присвойте результаты функции onSnapshot переменной guestbookListener .

    Обработчик onSnapshot в Firestore возвращает функцию отмены подписки, которую вы сможете использовать для отмены обработки события snapshot позже.
    // ...
    // 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);
        });
      });
    }
    
  3. Добавьте под этим кодом новую функцию с именем unsubscribeGuestbook . Проверьте, не является ли переменная guestbookListener нулевой, затем вызовите функцию для отмены подписки на слушатель.
    // ...
    // Unsubscribe from guestbook updates
    function unsubscribeGuestbook() {
      if (guestbookListener != null) {
        guestbookListener();
        guestbookListener = null;
      }
    }
    

Наконец, добавьте новые функции в функцию обратного вызова onAuthStateChanged .

  1. Добавьте subscribeGuestbook() в конец условия if (user) .
  2. Добавьте 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. Дополнительный шаг: Примените полученные знания на практике.

Зафиксируйте статус подтверждения участия участника.

Сейчас ваше приложение позволяет людям начать общение только в том случае, если они заинтересованы в мероприятии. Кроме того, узнать о том, что кто-то придёт, можно только по его сообщению в чате. Давайте организуем всё так, чтобы люди знали, сколько человек придёт.

Вы добавите переключатель для регистрации желающих посетить мероприятие, а затем соберете данные о количестве пришедших.

  1. В StackBlitz перейдите к файлу index.html .
  2. В 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 аутентификации для сохранения ответа в базе данных.

  1. В StackBlitz перейдите к файлу index.js .
  2. В самом верху найдите оператор импорта 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';
    
  3. В конце функции main() добавьте следующий код для отслеживания статуса подтверждения участия (RSVP):
    async function main() {
      // ...
    
      // Listen to RSVP responses
      rsvpYes.onclick = async () => {
      };
      rsvpNo.onclick = async () => {
      };
    }
    main();
    
    
  4. Далее создайте новую коллекцию под названием 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 в коллекцию.

  1. Что касается коллекции 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;
        }
      }
    }
    
  2. Нажмите «Опубликовать» , чтобы применить новые правила.

Добавить правила проверки

  1. Добавьте правила проверки данных, чтобы убедиться, что в документе присутствуют все ожидаемые поля:
    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;
    
        }
      }
    }
    
  2. Не забудьте нажать кнопку «Опубликовать» , чтобы развернуть ваши правила!

(Необязательно) Теперь вы можете просмотреть результаты нажатия кнопок. Перейдите на панель управления Cloud Firestore в консоли Firebase.

Прочитайте статус подтверждения участия.

Теперь, когда вы записали ответы, давайте посмотрим, кто придёт, и отобразим это в пользовательском интерфейсе.

  1. В StackBlitz перейдите к файлу index.html .
  2. В description-container добавьте новый элемент с идентификатором number-attending .
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

Далее зарегистрируйте слушателя для сбора данных attendees и подсчитайте количество ответов «ДА» :

  1. В StackBlitz перейдите к файлу index.js .
  2. В конце функции 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();
    

Наконец, выделим кнопку, соответствующую текущему статусу.

  1. Создайте функцию, которая проверяет, есть ли запись текущего 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';
          }
        }
      });
    }
    
  2. Также давайте создадим функцию для отписки. Она будет использоваться, когда пользователь выходит из системы.
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. Вызывайте функции из обработчика аутентификации.
    // ...
    // 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();
        }
      });
    
  4. Попробуйте войти в систему под несколькими пользователями и посмотрите, как увеличивается количество нажатий кнопки «ДА» .

Предварительный просмотр приложения

скриншот этого шага

11. Поздравляем!

Вы использовали Firebase для создания интерактивного веб-приложения, работающего в режиме реального времени!

Что мы рассмотрели

  • Аутентификация Firebase
  • FirebaseUI
  • Облачный Firestore
  • Правила безопасности Firebase

Следующие шаги

  • Хотите узнать больше о рабочем процессе разработчика Firebase? Ознакомьтесь с практическим руководством по использованию эмулятора Firebase, чтобы узнать, как тестировать и запускать ваше приложение полностью локально.
  • Хотите узнать больше о других продуктах Firebase? Возможно, вам нужно хранить файлы изображений, которые загружают пользователи? Или отправлять уведомления своим пользователям? Ознакомьтесь с Firebase Web CodeLab , где подробно рассматриваются многие другие продукты Firebase для веб-разработки.
  • Хотите узнать больше о Cloud Firestore? Возможно, вас интересуют подколлекции и транзакции? Перейдите на веб-платформу Cloud Firestore , где вы найдете более подробную информацию о Cloud Firestore. Или посмотрите этот сериал на YouTube, чтобы познакомиться с Cloud Firestore !

Узнать больше

Как всё прошло?

Нам очень важны ваши отзывы! Пожалуйста, заполните (очень) короткую форму здесь .