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

1. Обзор

В этом codelab, вы узнаете некоторые из основ Firebase для создания интерактивных веб - приложений. Вы создадите приложение для ответа на приглашение на мероприятие и чат для гостевой книги, используя несколько продуктов Firebase.

59abdefbcc23bbbe.png

Что ты узнаешь

  • Аутентифицируйте пользователей с помощью Firebase Authentication и FirebaseUI.
  • Синхронизируйте данные с помощью Cloud Firestore.
  • Напишите правила безопасности Firebase для защиты базы данных.

Что тебе понадобится

  • Любой браузер, например Chrome.
  • Доступ к stackblitz.com (нет учетной записи или входа в систему необходимо).
  • Учетная запись Google, например учетная запись Gmail. Мы рекомендуем учетную запись электронной почты, которую вы уже используете для своей учетной записи GitHub. Это позволяет вам использовать расширенные функции в StackBlitz.
  • Пример кода codelab. См. Следующий шаг, чтобы узнать, как получить код.

2. Получите стартовый код.

В этом codelab, вы строите приложение с помощью StackBlitz , онлайн редактор , который имеет несколько Firebase рабочие процессы интегрированы в него. Stackblitz не требует установки программного обеспечения или специальной учетной записи StackBlitz.

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

  1. Перейти к этому URL для стартового кода: https://stackblitz.com/edit/firebase-gtk-web-start
  2. В верхней части страницы StackBlitz, нажмите Вилка: f5135360aef481cc.png

Теперь у вас есть копия начального кода в виде вашего собственного проекта StackBlitz. Так как вы не вошли в ваш аккаунт называется @anonymous , но проект имеет уникальное имя, наряду с уникальным 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>

<!-- ... -->

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

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

908cc57ce3a5b5fe.png

4. Создайте и настройте проект Firebase.

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

Создать проект Firebase

  1. Войдите Firebase .
  2. В Firebase консоли, нажмите кнопку Add Project (или Создать проект), затем название вашего проекта Firebase Firebase-Web-Codelab.
    a67c239f8cc7f4b5.png
  3. Щелкните по параметрам создания проекта. Примите условия Firebase, если будет предложено. Пропустите настройку Google Analytics, потому что вы не будете использовать Analytics для этого приложения.

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

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

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

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

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

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

Для того, чтобы позволить пользователям войти в веб - приложение, вы будете использовать E - mail / пароль входа в методе для этого codelab:

  1. В Firebase консоли выберите команду Построить в левой панели.
  2. Нажмите Authentication, затем нажмите Вход в систему вкладке метод (или нажмите здесь , чтобы перейти непосредственно к Знамение-во вкладке метод).
  3. Нажмите E - mail / пароль в регистрации в списке поставщиков, установите переключатель в положение Enable, затем нажмите кнопку Сохранить.
    4c88427cfd869bee.png

Включить Cloud Firestore

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

Включить Cloud Firestore:

  1. В разделе сборки Firebase консоли, нажмите Firestore базы данных.
  2. Нажмите кнопку Создать базу данных.
    3ce19fd6467e51c5.png
  3. Выберите Пуск в опции тестового режима. Прочтите заявление об отказе от ответственности о правилах безопасности. Тестовый режим гарантирует, что вы можете свободно писать в базу данных во время разработки. Нажмите кнопку Далее.
    56369cebb9300eb.png
  4. Выберите расположение для вашей базы данных (вы можете просто использовать значение по умолчанию). Учтите, однако, что это местоположение не может быть изменено позже.
    32f815f4648c3174.png
  5. Нажмите Готово.

5. Добавьте и настройте Firebase.

Теперь, когда у вас есть проект Firebase и включены некоторые службы, вам нужно указать коду, что вы хотите использовать Firebase, а также указать, какой проект Firebase использовать.

Добавьте библиотеки Firebase

Чтобы ваше приложение могло использовать Firebase, вам необходимо добавить в приложение библиотеки Firebase. Есть несколько способов сделать это, как описано в документации Firebase . Например, вы можете добавить библиотеки из CDN Google или установить их локально с помощью npm, а затем упаковать их в свое приложение, если вы используете Browserify.

StackBlitz обеспечивает автоматическое объединение, поэтому вы можете добавлять библиотеки Firebase с помощью операторов импорта. Вы будете использовать модульные (v9) версии библиотек, которые помогают уменьшить общий размер веб-страницы с помощью процесса, называемого «встряхивание дерева». Вы можете узнать больше о модульных SDKs в документации .

Для создания этого приложения вы используете библиотеки Firebase Authentication, FirebaseUI и Cloud Firestore. Для этого codelab следующие операторы импорта уже включены в верхней части 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

  1. Назад в Firebase консоли перейдите к главной странице вашего проекта, нажав кнопку Обзор проекта в верхнем левом углу.
  2. В центре страницы обзора вашего проекта щелкните значок Интернета b286f3d215e1f578.png для создания нового веб-приложения Firebase.
    c167e9526fad2825.png
  3. Зарегистрировать приложение с никем Web App.
  4. Для этого codelab, НЕ флажок также настроить Firebase хостинг для этого приложения. Пока вы будете использовать панель предварительного просмотра StackBlitz.
  5. Выберите Зарегистрировать приложение.
    c85ac8aa351e2560.png
  6. Скопируйте объект конфигурации Firebase в буфер обмена.
    ed1e598c6132f734.png
  7. Нажмите Продолжить , чтобы утешить.

Добавьте в приложение объект конфигурации Firebase:

  1. Еще в StackBlitz, перейдите к index.js файл.
  2. Найдите Add Firebase project configuration object here строку комментария, а затем вставьте конфигурации фрагмент чуть ниже комментария.
  3. Добавьте 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.appspot.com",
      messagingSenderId: "random-unique-string",
      appId: "random-unique-string",
    };
    
    // Initialize Firebase
    initializeApp(firebaseConfig);
    

6. Добавьте вход пользователя (RSVP)

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

Аутентифицируйте своих пользователей с помощью входа по электронной почте и FirebaseUI

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

FirebaseUI требует конфигурации (см параметров в документации ) , что делает две вещи:

  • Сообщает FirebaseUI , что вы хотите использовать E - mail / пароль входа в методе.
  • Обрабатывает обратный вызов для успешного входа и возвращает false, чтобы избежать перенаправления. Вы не хотите, чтобы страница обновлялась, потому что вы создаете одностраничное веб-приложение.

Добавьте код для инициализации FirebaseUI Auth

  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 значения , как показано ниже , поскольку для этого codelab, уже есть крючки для этих конкретных идентификаторов в index.js файла.

    Обратите внимание , что в index.html файла, есть контейнер с ID 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>
    <!-- ... -->
    
    App Предварительный просмотр
    ab9ad7d61bb7b28c.png
  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 , убедитесь , что вы включили E - mail / пароль в качестве входа в поставщике в консоли Firebase.
    Предварительный просмотр приложения
    3024f90b52ad55fe.png
  2. Перейти к приборной панели аутентификации в консоли Firebase. На вкладке Users, вы должны увидеть информацию об учетной записи , которую вы ввели для входа в приложение. 682fc0eca86a99fc.png

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

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

Вы будете использовать обратный вызов прослушивателя состояния 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);
      }
    });
    

Теперь кнопка в вашем приложении должны показать LOGOUT, и он должен вернуться к RSVP , когда он нажал.

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

4c540450924f1607.png

7. Пишите сообщения в Cloud Firestore.

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

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

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

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

b447950f9f993789.png

Добавить сообщения в 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>
    
    <!-- ... -->
    

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

4a892284443cf73d.png

Пользователь , нажав кнопку SEND вызовет фрагмент кода ниже. Он добавляет содержимое поля ввода сообщения в guestbook коллекции базы данных. В частности, addDoc метод добавляет содержание сообщения в новый документ (с автоматически генерируемым ID) в 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. Теперь мы сохранить ссылку на Firestore db объекта права после 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. Введите сообщение , такие как «Эй!», А затем нажмите SEND.

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

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

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

Консоль Firebase

713870af0b3b63c.png

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 в своем приложении!

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

e30df0a9614bae7d.png

9. Установите основные правила безопасности.

Изначально вы настроили Cloud Firestore для использования тестового режима, что означает, что ваша база данных открыта для чтения и записи. Однако вам следует использовать тестовый режим только на самых ранних этапах разработки. Рекомендуется устанавливать правила безопасности для своей базы данных при разработке приложения. Безопасность должна быть неотъемлемой частью структуры и поведения вашего приложения.

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

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

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

7767a2d2e64e7275.png

Определить коллекции

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

В 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 запрос внутри слушателя аутентификации. В противном случае возникнут ошибки разрешения, и приложение будет отключено, когда пользователь выйдет из системы.

  1. Вытяните коллекции гостевой книги onSnapshot слушатель в новую функцию под названием subscribeGuestbook . Кроме того , присвоить результаты onSnapshot функции к guestbookListener переменной.

    Firestore onSnapshot слушатель возвращается в отписках функции, вы будете иметь возможность использовать для отмены снимки слушателя позже.
    // ...
    // Listen to guestbook updates
    // 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);
        });
      });
    }
    
  2. Добавить новую функцию под названием 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>
    <!-- ... -->
    

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

73ca99ca35c13ee7.png

Затем зарегистрируйте прослушиватель нажатий кнопок. Если пользователь нажимает кнопку YES, а затем использовать их подлинность 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 нажата.
  5. Установить ссылку на эту 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 коллекции, так как вы использовали аутентификации 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

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

  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 и подсчет кликов YES.
    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. Создайте функцию , которая проверяет , имеет ли текущий Authentication 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();
          // Subcribe 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. Попробуйте войти в систему как нескольких пользователей и видеть увеличение счетчика с каждой дополнительной кнопки ДА мыши.

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

3df607d3e0b3c35.png

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

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

Что мы покрыли

  • Проверка подлинности Firebase
  • FirebaseUI
  • Cloud Firestore
  • Правила безопасности Firebase

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

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

Учить больше

Как прошло?

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