Веб-лаборатория Firebase

1. Обзор

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

3b1284f5144b54f6.png

Что вы узнаете

  • Синхронизируйте данные с помощью Cloud Firestore и Cloud Storage for Firebase.
  • Аутентифицируйте своих пользователей с помощью Firebase Authentication.
  • Разверните свое веб-приложение на хостинге Firebase.
  • Отправляйте уведомления с помощью Firebase Cloud Messaging.
  • Соберите данные о производительности вашего веб-приложения.

Что вам понадобится

  • IDE/текстовый редактор по вашему выбору, например WebStorm , Atom , Sublime или VS Code.
  • Менеджер пакетов npm , который обычно поставляется с Node.js.
  • Терминал/консоль
  • Браузер на ваш выбор, например Chrome
  • Образец кода лаборатории кода (см. следующий шаг лаборатории кода, чтобы узнать, как получить код.)

2. Получите пример кода

Клонируйте репозиторий GitHub лаборатории кода из командной строки:

git clone https://github.com/firebase/codelab-friendlychat-web

В качестве альтернативы, если у вас не установлен git, вы можете загрузить репозиторий в виде ZIP-файла .

Импортировать стартовое приложение

Используя вашу IDE, откройте или импортируйте каталог 📁 web-start из клонированного репозитория. Этот каталог 📁 web-start содержит начальный код для лаборатории кода, которая будет полнофункциональным веб-приложением для чата.

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

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

  1. Войдите в Firebase .
  2. В консоли Firebase нажмите «Добавить проект» и назовите свой проект Firebase «FriendlyChat» . Запомните идентификатор проекта Firebase.
  3. Снимите флажок Включить Google Analytics для этого проекта.
  4. Щелкните Создать проект .

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

  • Firebase Authentication , чтобы ваши пользователи могли легко входить в ваше приложение.
  • Cloud Firestore для сохранения структурированных данных в облаке и получения мгновенных уведомлений при изменении данных.
  • Облачное хранилище для Firebase для сохранения файлов в облаке.
  • Хостинг Firebase для размещения и обслуживания ваших активов.
  • Firebase Cloud Messaging для отправки push-уведомлений и отображения всплывающих уведомлений в браузере.
  • Firebase Performance Monitoring для сбора данных о производительности пользователей для вашего приложения.

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

Добавьте веб-приложение Firebase в проект

  1. Щелкните веб-значок 58d6543a156e56f9.png для создания нового веб-приложения Firebase.
  2. Зарегистрируйте приложение под псевдонимом «Дружественный чат» , затем установите флажок «Также настроить Firebase Hosting для этого приложения ». Щелкните Зарегистрировать приложение .
  3. На следующем шаге вы увидите объект конфигурации. Скопируйте только объект JS (а не окружающий HTML) в firebase-config.js.

Зарегистрировать скриншот веб-приложения

Включить вход через Google для проверки подлинности Firebase

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

Вам нужно включить вход через Google :

  1. В консоли Firebase найдите раздел «Сборка» на левой панели.
  2. Щелкните «Аутентификация» , затем щелкните вкладку «Метод входа» (или щелкните здесь , чтобы сразу перейти туда).
  3. Включите поставщика услуг входа Google , затем нажмите «Сохранить» .
  4. Установите общедоступное имя вашего приложения на Дружественный чат и выберите адрес электронной почты службы поддержки Project в раскрывающемся меню.
  5. Настройте экран согласия OAuth в Google Cloud Console и добавьте логотип:

d89fb3873b5d36ae.png

Включить облачное хранилище Firestore

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

Вам нужно включить Cloud Firestore:

  1. В разделе «Сборка» консоли Firebase нажмите «База данных Firestore» .
  2. Нажмите Создать базу данных на панели Cloud Firestore.

729991a081e7cd5.png

  1. Выберите параметр «Начать в тестовом режиме» , затем нажмите «Далее» после прочтения заявления об отказе от ответственности в отношении правил безопасности.

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

77e4986cbeaf9dee.png

  1. Установите место, где хранятся ваши данные Cloud Firestore. Вы можете оставить это значение по умолчанию или выбрать ближайший к вам регион. Нажмите «Готово» , чтобы подготовить Firestore.

9f2bb0d4e7ca49c7.png

Включить облачное хранилище

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

Вам нужно включить облачное хранилище:

  1. В разделе «Сборка» консоли Firebase нажмите «Хранилище» .
  2. Если кнопки «Начать» нет, это означает, что облачное хранилище уже включено, и вам не нужно выполнять описанные ниже действия.
  3. Нажмите «Начать» .
  4. Прочтите заявление об отказе от ответственности в отношении правил безопасности для вашего проекта Firebase, затем нажмите «Далее» .

С правилами безопасности по умолчанию любой аутентифицированный пользователь может записывать что угодно в Cloud Storage. Мы сделаем наше хранилище более безопасным позже в этой лаборатории кода.

62f1afdcd1260127.png

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

1d7f49ebaddb32fc.png

4. Установите интерфейс командной строки Firebase

Интерфейс командной строки (CLI) Firebase позволяет вам использовать Firebase Hosting для локального обслуживания вашего веб-приложения, а также для развертывания вашего веб-приложения в проекте Firebase.

  1. Установите CLI, выполнив следующую команду npm:
npm -g install firebase-tools
  1. Убедитесь, что CLI установлен правильно, выполнив следующую команду:
firebase --version

Убедитесь, что версия интерфейса командной строки Firebase — 4.1.0 или более поздняя.

  1. Авторизуйте интерфейс командной строки Firebase, выполнив следующую команду:
firebase login

Мы настроили шаблон веб-приложения, чтобы получить конфигурацию вашего приложения для Firebase Hosting из локального каталога вашего приложения (репозиторий, который вы клонировали ранее в лаборатории кода). Но чтобы получить конфигурацию, нам нужно связать ваше приложение с вашим проектом Firebase.

  1. Убедитесь, что ваша командная строка обращается к локальному каталогу web-start вашего приложения.
  2. Свяжите свое приложение с проектом Firebase, выполнив следующую команду:
firebase use --add
  1. При появлении запроса выберите идентификатор проекта , а затем дайте псевдоним вашему проекту Firebase.

Псевдоним полезен, если у вас несколько сред (производственная, промежуточная и т. д.). Однако для этой кодлабы давайте просто воспользуемся псевдонимом default .

  1. Следуйте оставшимся инструкциям в командной строке.

5. Запустите стартовое приложение локально

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

  1. В консоли из каталога web-start выполните следующую команду Firebase CLI:
firebase serve --only hosting
  1. Ваша командная строка должна отобразить следующий ответ:
✔  hosting: Local server: http://localhost:5000

Мы используем эмулятор Firebase Hosting для локального обслуживания нашего приложения. Теперь веб-приложение должно быть доступно по адресу http://localhost:5000 . Обслуживаются все файлы, расположенные в подкаталоге public .

  1. В браузере откройте свое приложение по адресу http://localhost:5000 .

Вы должны увидеть пользовательский интерфейс вашего приложения FriendlyChat, который (пока!) не работает:

4c23f9475228cef4.png

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

Давайте теперь создадим чат в реальном времени!

6. Импортируйте и настройте Firebase

Импорт Firebase SDK

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

Мы собираемся получить Firebase SDK от npm и использовать Webpack для сборки нашего кода. Мы делаем это для того, чтобы Webpack мог удалить любой ненужный код, сохраняя размер нашего пакета JS небольшим, чтобы наше приложение загружалось как можно быстрее. Для этой кодовой лаборатории мы уже создали файл web-start/package.json , который включает Firebase SDK в качестве зависимости, а также импортировали необходимые функции вверху web-start/src/index.js .

пакет.json

"dependencies": {
  "firebase": "^9.0.0"
}

index.js

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup,
  signOut,
} from 'firebase/auth';
import {
  getFirestore,
  collection,
  addDoc,
  query,
  orderBy,
  limit,
  onSnapshot,
  setDoc,
  updateDoc,
  doc,
  serverTimestamp,
} from 'firebase/firestore';
import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';

Во время этой лаборатории кода мы собираемся использовать Firebase Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging и Performance Monitoring, поэтому мы импортируем все их библиотеки. В своих будущих приложениях убедитесь, что вы импортируете только те части Firebase, которые вам нужны, чтобы сократить время загрузки вашего приложения.

Установите Firebase SDK и запустите сборку Webpack.

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

  1. Откройте новое окно терминала
  2. Убедитесь, что вы находитесь в каталоге web-start
  3. Запустите npm install , чтобы загрузить Firebase SDK.
  4. Запустите npm run start , чтобы запустить Webpack. Теперь Webpack будет постоянно перестраивать наш исходный код для остальной части лаборатории кода.

Настроить Firebase

Нам также нужно настроить Firebase SDK, чтобы указать, какой проект Firebase мы используем.

  1. Перейдите к настройкам вашего проекта в консоли Firebase.
  2. В карточке «Ваши приложения» выберите никнейм приложения, для которого вам нужен объект конфигурации.
  3. Выберите «Конфигурация» на панели фрагментов кода Firebase SDK.
  4. Скопируйте фрагмент объекта конфигурации, затем добавьте его в web-start/src/firebase-config.js .

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

Теперь перейдите в конец web-start/src/index.js и инициализируйте Firebase:

index.js

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

7. Настройте вход пользователя

Теперь Firebase SDK должен быть готов к использованию, так как он импортирован и инициализирован в index.js . Теперь мы собираемся реализовать вход пользователя с помощью Firebase Authentication .

Аутентифицируйте своих пользователей с помощью Google Sign-In

В приложении, когда пользователь нажимает кнопку «Войти через Google» , срабатывает функция signIn . (Мы уже настроили это для вас!) Для этой лаборатории кода мы хотим разрешить Firebase использовать Google в качестве поставщика удостоверений. Мы будем использовать всплывающее окно, но в Firebase доступно несколько других методов .

  1. В каталоге web-start в подкаталоге src/ откройте index.js .
  2. Найдите функцию signIn .
  3. Замените всю функцию следующим кодом.

index.js

// Signs-in Friendly Chat.
async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider);
}

Функция signOut запускается, когда пользователь нажимает кнопку «Выход» .

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию signOutUser .
  3. Замените всю функцию следующим кодом.

index.js

// Signs-out of Friendly Chat.
function signOutUser() {
  // Sign out of Firebase.
  signOut(getAuth());
}

Отслеживание состояния аутентификации

Чтобы соответствующим образом обновить наш пользовательский интерфейс, нам нужен способ проверить, вошел ли пользователь в систему или вышел из нее. С помощью Firebase Authentication вы можете зарегистрировать наблюдателя в состоянии аутентификации, который будет запускаться каждый раз при изменении состояния аутентификации.

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию initFirebaseAuth .
  3. Замените всю функцию следующим кодом.

index.js

// Initialize firebase auth
function initFirebaseAuth() {
  // Listen to auth state changes.
  onAuthStateChanged(getAuth(), authStateObserver);
}

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

Отображение информации о вошедшем в систему пользователе

Мы хотим отобразить изображение профиля и имя пользователя, вошедшего в систему, в верхней панели нашего приложения. В Firebase данные вошедшего пользователя всегда доступны в объекте currentUser . Ранее мы настроили функцию authStateObserver так, чтобы она срабатывала, когда пользователь входит в систему, чтобы наш пользовательский интерфейс обновлялся соответствующим образом. При срабатывании он вызовет getProfilePicUrl и getUserName .

  1. Вернитесь к файлу src/index.js .
  2. Найдите функции getProfilePicUrl и getUserName .
  3. Замените обе функции следующим кодом.

index.js

// Returns the signed-in user's profile Pic URL.
function getProfilePicUrl() {
  return getAuth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return getAuth().currentUser.displayName;
}

Мы отображаем сообщение об ошибке, если пользователь пытается отправить сообщения, когда пользователь не вошел в систему. (Вы можете попробовать, однако!) Итак, нам нужно определить, действительно ли пользователь вошел в систему.

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию isUserSignedIn .
  3. Замените всю функцию следующим кодом.

index.js

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!getAuth().currentUser;
}

Тестовый вход в приложение

  1. Если ваше приложение все еще обслуживается, обновите его в браузере. В противном случае запустите firebase serve --only hosting в командной строке, чтобы начать обслуживание приложения с http://localhost:5000 , а затем откройте его в своем браузере.
  2. Войдите в приложение, используя кнопку входа и свою учетную запись Google. Если вы видите сообщение об ошибке с указанием auth/operation-not-allowed , убедитесь, что вы включили вход через Google в качестве поставщика аутентификации в консоли Firebase.
  3. После входа в систему должно отображаться изображение вашего профиля и имя пользователя: c7401b3d44d0d78b.png

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

В этом разделе мы запишем некоторые данные в Cloud Firestore, чтобы мы могли заполнить пользовательский интерфейс приложения. Это можно сделать вручную с помощью консоли Firebase , но мы сделаем это в самом приложении, чтобы продемонстрировать базовую запись в Cloud Firestore.

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

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

688d7bc5fb662b57.png

Добавляйте сообщения в Cloud Firestore

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

В этом разделе вы добавите функциональность, позволяющую пользователям записывать новые сообщения в вашу базу данных. Пользователь, нажав кнопку ОТПРАВИТЬ , активирует приведенный ниже фрагмент кода. Он добавляет объект сообщения с содержимым полей сообщений в ваш экземпляр Cloud Firestore в коллекции messages . Метод add() добавляет в коллекцию новый документ с автоматически сгенерированным идентификатором.

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию saveMessage .
  3. Замените всю функцию следующим кодом.

index.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

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

  1. Если ваше приложение все еще обслуживается, обновите его в браузере. В противном случае запустите firebase serve --only hosting в командной строке, чтобы начать обслуживание приложения с http://localhost:5000 , а затем откройте его в своем браузере.
  2. После входа введите сообщение, например "Привет!", а затем нажмите ОТПРАВИТЬ . Это запишет сообщение в Cloud Firestore. Однако вы еще не увидите данные в реальном веб-приложении, потому что нам все еще нужно реализовать извлечение данных (следующий раздел лаборатории кода).
  3. Вы можете увидеть новое добавленное сообщение в консоли Firebase. Откройте консоль Firebase. В разделе «Сборка» нажмите «База данных Firestore» (или нажмите здесь и выберите свой проект), и вы должны увидеть коллекцию сообщений с вашим новым добавленным сообщением:

6812efe7da395692.png

9. Читать сообщения

Синхронизировать сообщения

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

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

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию loadMessages .
  3. Замените всю функцию следующим кодом.

index.js

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                      message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

Чтобы прослушать сообщения в базе данных, мы создаем запрос к коллекции, используя функцию collection , чтобы указать, в какой коллекции находятся данные, которые мы хотим прослушать. В приведенном выше коде мы прослушиваем изменения в messages коллекция, в которой хранятся сообщения чата. Мы также применяем ограничение, прослушивая только последние 12 сообщений, используя .limit(12) и упорядочивая сообщения по дате, используя orderBy('timestamp', 'desc') , чтобы получить 12 самых новых сообщений.

Функция onSnapshot принимает запрос в качестве первого параметра, а функцию обратного вызова — в качестве второго. Функция обратного вызова будет запущена при любых изменениях в документах, соответствующих запросу. Это может произойти, если сообщение будет удалено, изменено или добавлено. Подробнее об этом можно прочитать в документации Cloud Firestore .

Проверка синхронизации сообщений

  1. Если ваше приложение все еще обслуживается, обновите его в браузере. В противном случае запустите firebase serve --only hosting в командной строке, чтобы начать обслуживание приложения с http://localhost:5000 , а затем откройте его в своем браузере.
  2. Сообщения, которые вы создали ранее в базе данных, должны отображаться в пользовательском интерфейсе FriendlyChat (см. ниже). Не стесняйтесь писать новые сообщения; они должны появиться мгновенно.
  3. (Необязательно) Вы можете попробовать вручную удалить, изменить или добавить новые сообщения непосредственно в разделе «База данных» консоли Firebase; любые изменения должны быть отражены в пользовательском интерфейсе.

Поздравляем! Вы читаете документы Cloud Firestore в своем приложении!

2168dec79b573d07.png

10. Отправляйте изображения

Теперь мы добавим функцию, которая обменивается изображениями.

В то время как Cloud Firestore хорош для хранения структурированных данных, Cloud Storage лучше подходит для хранения файлов. Облачное хранилище для Firebase — это служба хранения файлов/BLOB-объектов, и мы будем использовать ее для хранения любых изображений, которыми пользователь делится с помощью нашего приложения.

Сохранение изображений в облачном хранилище

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

  1. Создает сообщение чата «заполнитель» в ленте чата, чтобы пользователи видели анимацию «Загрузка», пока мы загружаем изображение.
  2. Загружает файл изображения в облачное хранилище по этому пути: /<uid>/<messageId>/<file_name>
  3. Создает общедоступный URL-адрес для файла изображения.
  4. Обновляет сообщение чата URL-адресом недавно загруженного файла изображения вместо временного загружаемого изображения.

Теперь вы добавите функциональность для отправки изображения:

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию saveImageMessage .
  3. Замените всю функцию следующим кодом.

index.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
  try {
    // 1 - We add a message with a loading icon that will get updated with the shared image.
    const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      imageUrl: LOADING_IMAGE_URL,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
    const newImageRef = ref(getStorage(), filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    });
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

Тестовая отправка изображений

  1. Если ваше приложение все еще обслуживается, обновите его в браузере. В противном случае запустите firebase serve --only hosting в командной строке, чтобы начать обслуживание приложения с http://localhost:5000 , а затем откройте его в своем браузере.
  2. После входа нажмите кнопку загрузки изображения 13734cb66773e5a3.png и выберите файл изображения с помощью средства выбора файлов. Если вы ищете изображение, не стесняйтесь использовать это красивое изображение кофейной чашки .
  3. В пользовательском интерфейсе приложения должно появиться новое сообщение с выбранным вами изображением: 3b1284f5144b54f6.png

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

11. Показать уведомления

Теперь мы добавим поддержку уведомлений браузера. Приложение будет уведомлять пользователей о появлении новых сообщений в чате. Firebase Cloud Messaging (FCM) — это кроссплатформенное решение для обмена сообщениями, которое позволяет надежно доставлять сообщения и уведомления бесплатно.

Добавьте работника службы FCM

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

  1. Из каталога web-start в каталоге src откройте firebase-messaging-sw.js .
  2. Добавьте в этот файл следующее содержимое.

firebase-сообщения-sw.js

// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';

const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');

Сервисному работнику просто нужно загрузить и инициализировать Firebase Cloud Messaging SDK, который позаботится об отображении уведомлений.

Получить токены устройства FCM

Когда уведомления включены на устройстве или в браузере, вам будет предоставлен токен устройства . Этот токен устройства — это то, что мы используем для отправки уведомления на конкретное устройство или конкретный браузер.

Когда пользователь входит в систему, мы вызываем функцию saveMessagingDeviceToken . Здесь мы получим токен устройства FCM из браузера и сохраним его в Cloud Firestore.

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию saveMessagingDeviceToken .
  3. Замените всю функцию следующим кодом.

index.js

// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
  try {
    const currentToken = await getToken(getMessaging());
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to Cloud Firestore.
      const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
      await setDoc(tokenRef, { uid: getAuth().currentUser.uid });

      // This will fire when a message is received while the app is in the foreground.
      // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
      onMessage(getMessaging(), (message) => {
        console.log(
          'New foreground notification from Firebase Messaging!',
          message.notification
        );
      });
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  } catch(error) {
    console.error('Unable to get messaging token.', error);
  };
}

Однако изначально этот код не будет работать. Чтобы ваше приложение могло получить токен устройства, пользователь должен предоставить вашему приложению разрешение на отображение уведомлений (следующий шаг лаборатории кода).

Запросить разрешения на отображение уведомлений

Если пользователь еще не предоставил вашему приложению разрешение на отображение уведомлений, вам не будет предоставлен токен устройства. В этом случае мы вызываем метод firebase.messaging().requestPermission() , который отобразит диалоговое окно браузера с запросом на это разрешение ( в поддерживаемых браузерах ).

8b9d0c66dc36153d.png

  1. Вернитесь к файлу src/index.js .
  2. Найдите функцию requestNotificationsPermissions .
  3. Замените всю функцию следующим кодом.

index.js

// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  const permission = await Notification.requestPermission();
  
  if (permission === 'granted') {
    console.log('Notification permission granted.');
    // Notification permission granted.
    await saveMessagingDeviceToken();
  } else {
    console.log('Unable to get permission to notify.');
  }
}

Получите токен вашего устройства

  1. Если ваше приложение все еще обслуживается, обновите его в браузере. В противном случае запустите firebase serve --only hosting в командной строке, чтобы начать обслуживание приложения с http://localhost:5000 , а затем откройте его в своем браузере.
  2. После входа в систему должно появиться диалоговое окно разрешения уведомлений: bd3454e6dbfb6723.png
  3. Щелкните Разрешить .
  4. Откройте консоль JavaScript вашего браузера. Вы должны увидеть следующее сообщение: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Скопируйте токен вашего устройства. Он понадобится вам для следующего этапа кодлаба.

Отправить уведомление на ваше устройство

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

  1. Откройте вкладку Cloud Messaging консоли Firebase .
  2. Нажмите «Новое уведомление».
  3. Введите заголовок уведомления и текст уведомления.
  4. В правой части экрана нажмите «отправить тестовое сообщение».
  5. Введите токен устройства, который вы скопировали из консоли JavaScript вашего браузера, затем нажмите знак плюс ("+")
  6. Нажмите "тест"

Если ваше приложение находится на переднем плане, вы увидите уведомление в консоли JavaScript.

Если ваше приложение работает в фоновом режиме, в браузере должно появиться уведомление, как в этом примере:

de79e8638a45864c.png

12. Правила безопасности Cloud Firestore

Посмотреть правила безопасности базы данных

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

При настройке проекта Firebase в начале этой лаборатории кода мы решили использовать правила безопасности по умолчанию «Тестовый режим», чтобы не ограничивать доступ к хранилищу данных. В консоли Firebase на вкладке «Правила» раздела «База данных» вы можете просмотреть и изменить эти правила.

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

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

Мы обновим правила, чтобы ограничить вещи, используя следующие правила:

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

Обновите правила безопасности базы данных

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

Чтобы обновить правила безопасности в консоли Firebase:

  1. Перейдите в раздел «База данных» на левой панели, а затем щелкните вкладку «Правила» .
  2. Замените правила по умолчанию, которые уже есть в консоли, на правила, показанные выше.
  3. Щелкните Опубликовать .

Чтобы обновить правила безопасности из локального файла:

  1. В каталоге web-start откройте firestore.rules .
  2. Замените правила по умолчанию, которые уже есть в файле, на правила, показанные выше.
  3. В каталоге web-start откройте firebase.json .
  4. Добавьте атрибут firestore.rules , указывающий на firestore.rules , как показано ниже. (Атрибут hosting уже должен быть в файле.)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Разверните правила безопасности с помощью интерфейса командной строки Firebase, выполнив следующую команду:
firebase deploy --only firestore
  1. Ваша командная строка должна отобразить следующий ответ:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

13. Правила безопасности облачного хранилища

Посмотреть правила безопасности Cloud Storage

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

При настройке проекта Firebase в начале этой лаборатории кода мы решили использовать правило безопасности Cloud Storage по умолчанию, которое разрешает использовать Cloud Storage только пользователям, прошедшим проверку подлинности. В консоли Firebase на вкладке «Правила» раздела «Хранилище» вы можете просматривать и изменять правила. Вы должны увидеть правило по умолчанию, которое позволяет любому вошедшему в систему пользователю читать и записывать любые файлы в вашем сегменте хранилища.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Мы обновим правила, чтобы сделать следующее:

  • Разрешить каждому пользователю писать только в свои определенные папки
  • Разрешить всем читать из облачного хранилища
  • Убедитесь, что загружаемые файлы являются изображениями
  • Ограничьте размер загружаемых изображений до 5 МБ.

Это можно реализовать с помощью следующих правил:

правила хранения

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

Обновите правила безопасности Cloud Storage

Есть два способа изменить правила безопасности хранилища: либо в консоли Firebase, либо из локального файла правил, развернутого с помощью интерфейса командной строки Firebase.

Чтобы обновить правила безопасности в консоли Firebase:

  1. Перейдите в раздел «Хранилище» с левой панели, а затем нажмите на вкладку «Правила» .
  2. Замените правило по умолчанию, которое уже есть в консоли, на правила, показанные выше.
  3. Щелкните Опубликовать .

Чтобы обновить правила безопасности из локального файла:

  1. В каталоге web-start откройте storage.rules .
  2. Замените правила по умолчанию, которые уже есть в файле, на правила, показанные выше.
  3. В каталоге web-start откройте firebase.json .
  4. Добавьте атрибут storage.rules , указывающий на файл storage.rules , как показано ниже. (Атрибуты hosting и database уже должны быть в файле.)

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Разверните правила безопасности с помощью интерфейса командной строки Firebase, выполнив следующую команду:
firebase deploy --only storage
  1. Ваша командная строка должна отобразить следующий ответ:
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

14. Собирайте данные о производительности

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

Существуют различные способы интеграции с JavaScript SDK Firebase Performance Monitoring. В этой лаборатории кода мы включили мониторинг производительности с URL-адресов хостинга . Обратитесь к документации , чтобы узнать о других способах включения SDK.

Автоматические трассировки

Поскольку мы уже импортировали getPerformance вверху web-start/src/index.js , нам просто нужно добавить одну строку, чтобы указать системе мониторинга производительности автоматически собирать для вас показатели загрузки страниц и сетевых запросов, когда пользователи посещают ваш развернутый сайт!

  1. В web-start/src/index.js добавьте следующую строку под существующим TODO , чтобы инициализировать мониторинг производительности.

index.js

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

Измерьте задержку первого входа (необязательно)

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

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

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

  1. Откройте public/index.html .
  2. Раскомментируйте тег script в следующей строке.

index.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

Чтобы узнать больше о первом полифилле input delay, загляните в документацию .

Просмотр данных о производительности

Поскольку вы еще не развернули свой сайт (вы развернете его на следующем шаге), вот снимок экрана, показывающий показатели производительности загрузки страниц, которые вы увидите в консоли Firebase в течение 30 минут после взаимодействия пользователей с вашим развернутым сайтом. :

29389131150f33d7.png

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

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

15. Разверните свое приложение с помощью хостинга Firebase

Firebase предлагает услугу хостинга для обслуживания ваших ресурсов и веб-приложений. Вы можете развернуть свои файлы на хостинге Firebase с помощью интерфейса командной строки Firebase. Перед развертыванием вам необходимо указать в файле firebase.json , какие локальные файлы следует развертывать. Для этой лаборатории кода мы уже сделали это за вас, потому что этот шаг был необходим для обслуживания наших файлов во время этой лаборатории кода. Настройки хостинга задаются в атрибуте hosting :

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

Эти настройки сообщают CLI, что мы хотим развернуть все файлы в каталоге ./public ( "public": "./public" ).

  1. Убедитесь, что ваша командная строка обращается к локальному каталогу web-start вашего приложения.
  2. Разверните файлы в проекте Firebase, выполнив следующую команду:
firebase deploy --except functions
  1. Консоль должна отобразить следующее:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Посетите свое веб-приложение, которое теперь полностью размещено в глобальной CDN с использованием хостинга Firebase на двух ваших собственных поддоменах Firebase:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Кроме того, вы можете запустить firebase open hosting:site в командной строке.

Посетите документацию, чтобы узнать больше о том, как работает Firebase Hosting .

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

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

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

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

  • Аутентификация Firebase
  • Облако Firestore
  • Firebase SDK для облачного хранилища
  • Облачные сообщения Firebase
  • Мониторинг производительности Firebase
  • Хостинг Firebase

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

Learn more