Лаборатория веб-кода AngularFire

1. Обзор

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

A chat app where users are discussing Firebase

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

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

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

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

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

Создайте репозиторий GitHub.

Исходный код codelab можно найти по адресу https://github.com/firebase/codelab-FriendlyChat-Web . Репозиторий содержит примеры проектов для нескольких платформ. Однако в этой лаборатории кода используется только каталог angularfire-start .

Скопируйте папку angularfire-start в свой репозиторий:

  1. Используя терминал, создайте новую папку на своем компьютере и перейдите в новый каталог:
    mkdir codelab-friendlyeats-web
    
    cd codelab-friendlyeats-web
    
  2. Используйте пакет giget npm, чтобы получить только папку angularfire-start :
    npx giget@latest gh:firebase/codelab-friendlychat-web/angularfire-start#master . --install
    
  3. Отслеживайте изменения локально с помощью git:
    git init
    
    git add .
    
    git commit -m "codelab starting point"
    
    git branch -M main
    
  4. Создайте новый репозиторий GitHub: https://github.com/new . Назовите это как угодно.
    1. GitHub предоставит вам новый URL-адрес репозитория, который выглядит как https://github.com/[user-name]/[repository-name].git или git@github.com:[user-name]/[repository-name].git . Скопируйте этот URL.
  5. Отправьте локальные изменения в новый репозиторий GitHub. Выполните следующую команду, заменив URL-адрес вашего репозитория на заполнитель your-repository-url .
    git remote add origin your-repository-url
    
    git push -u origin main
    
  6. Теперь вы должны увидеть стартовый код в своем репозитории GitHub.

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

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

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

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

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

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

Обновите тарифный план Firebase

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

Чтобы обновить проект до плана Blaze, выполните следующие действия:

  1. В консоли Firebase выберите обновление плана .
  2. В диалоговом окне выберите план Blaze, а затем следуйте инструкциям на экране, чтобы связать свой проект с учетной записью Cloud Billing.
    Если вам нужно создать учетную запись Cloud Billing, вам может потребоваться вернуться к процессу обновления в консоли Firebase, чтобы завершить обновление.

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

  1. Нажмите значок Интернета 58d6543a156e56f9.png чтобы создать новое веб-приложение Firebase.
  2. Зарегистрируйте приложение под ником Friendly Chat . Не устанавливайте флажок « Также настроить хостинг Firebase для этого приложения» . Нажмите Зарегистрировать приложение .
  3. На следующем шаге вы увидите объект конфигурации. Вам это сейчас не нужно. Нажмите «Продолжить работу с консолью» .

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

Настройка аутентификации

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

  1. В консоли Firebase перейдите к Authentication .
  2. Нажмите «Начать» .
  3. В столбце «Дополнительные поставщики» нажмите Google > Включить .
  4. В текстовом поле Общедоступное имя проекта введите запоминающееся имя, например My Next.js app .
  5. В раскрывающемся списке «Электронная почта поддержки проекта» выберите свой адрес электронной почты.
  6. Нажмите Сохранить .

Включить Cloud Firestore

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

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

  1. В консоли Firebase перейдите к Firestore .
  2. Нажмите Создать базу данных > Далее > Запустить в тестовом режиме > Далее .
    Позже в этой лабораторной работе вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не публикуйте приложение без добавления правил безопасности для вашей базы данных.
  3. Используйте местоположение по умолчанию или выберите местоположение по вашему выбору.
    Для реального приложения вам нужно выбрать местоположение, наиболее близкое к вашим пользователям. Обратите внимание, что это местоположение нельзя изменить позже, и оно также автоматически станет местоположением вашего сегмента Cloud Storage по умолчанию (следующий шаг).
  4. Нажмите Готово .

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

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

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

  1. В консоли Firebase перейдите к Storage .
  2. Нажмите «Начало работы» > «Начать в тестовом режиме» > «Далее» .
    Позже в этой лабораторной работе вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не публикуйте приложение без добавления правил безопасности для сегмента хранилища.
  3. Местоположение вашей корзины уже должно быть выбрано (из-за настройки Firestore на предыдущем шаге).
  4. Нажмите Готово .

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

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

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

Убедитесь, что версия Firebase CLI — vv13.9.0 или новее.

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

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

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

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

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

5. Установите AngularFire

Прежде чем запускать проект, убедитесь, что у вас настроены Angular CLI и AngularFire.

  1. В консоли выполните следующую команду:
npm install -g @angular/cli
  1. Затем в консоли из каталога angularfire-start выполните следующую команду Angular CLI:
ng add @angular/fire

Это установит все необходимые зависимости для вашего проекта.

  1. При появлении запроса снимите флажок ng deploy -- hosting с помощью пробела. С помощью клавиш со стрелками и пробела выберите следующие функции:
    • Authentication
    • Firestore
    • Cloud Messaging
    • Cloud Storage
  2. Нажмите enter и следуйте остальным подсказкам.
  3. Создайте коммит с сообщением «Установить AngularFire» и отправьте его в свой репозиторий GitHub.

6. Создайте серверную часть хостинга приложений.

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

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

  1. Перейдите на страницу хостинга приложений в консоли Firebase:

Нулевое состояние консоли хостинга приложений с кнопкой «Начать».

  1. Нажмите «Начать», чтобы начать процесс создания серверной части. Настройте свой бэкэнд следующим образом:
  2. Следуйте инструкциям на первом шаге, чтобы подключить созданный ранее репозиторий GitHub.
  3. Установите параметры развертывания:
    1. Сохраните корневой каталог как /
    2. Установите живую ветку на main
    3. Включить автоматическое внедрение
  4. Назовите свой бэкэнд friendlychat-codelab .
  5. В разделе «Создание или связывание веб-приложения Firebase» выберите веб-приложение, которое вы настроили ранее, из раскрывающегося списка «Выберите существующее веб-приложение Firebase».
  6. Нажмите «Завершить и развернуть». Через мгновение вы перейдете на новую страницу, где сможете увидеть состояние вашего нового бэкэнда хостинга приложений!
  7. После завершения развертывания выберите бесплатный домен в разделе «домены». Прежде чем начать работу, может потребоваться несколько минут из-за распространения DNS.

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

Нулевое состояние консоли хостинга приложений с кнопкой «Начать».

Вы должны увидеть экран входа в приложение FriendlyChat, который (пока!) не работает.

Приложение сейчас ничего не может сделать, но с вашей помощью это скоро произойдет!

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

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

Настроить Firebase

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

  1. Перейдите к настройкам проекта в консоли Firebase.
  2. В карточке «Ваши приложения» выберите никнейм приложения, для которого вам нужен объект конфигурации.
  3. Выберите «Конфигурация» на панели фрагментов Firebase SDK.

Вы обнаружите, что для вас был создан файл среды /angularfire-start/src/environments/environment.ts .

  1. Скопируйте фрагмент объекта конфигурации, а затем добавьте его в angularfire-start/src/firebase-config.js .

environment.ts

export const environment = {
  firebase: {
    apiKey: "API_KEY",
    authDomain: "PROJECT_ID.firebaseapp.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.appspot.com",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
  },
};

Посмотреть настройку AngularFire

Вы обнаружите, что функции, выбранные вами в консоли, были автоматически добавлены в файл /angularfire-start/src/app/app.config.ts . Это позволит вашему приложению использовать функции и возможности Firebase.

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

AngularFire теперь должен быть готов к использованию, поскольку он импортирован и инициализирован в app.config.ts . Теперь вы собираетесь реализовать вход пользователя с помощью Firebase Authentication .

Добавить авторизованный домен

Аутентификация Firebase позволяет входить в систему только из заданного списка доменов, которыми вы управляете. Добавьте свой бесплатный домен хостинга приложений в список доменов:

  1. Перейдите на Хостинг приложений .
  2. Скопируйте домен вашего серверного сервера.
  3. Перейдите к настройкам аутентификации .
  4. Выберите вкладку Авторизованные домены .
  5. Нажмите «Добавить домен» и вставьте домен серверной части хостинга приложений.

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

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

  1. В подкаталоге /src/app/services/ chat.service.ts .
  2. Найдите функцию login .
  3. Замените всю функцию следующим кодом.

chat.service.ts

// Signs-in Friendly Chat.
login() {
    signInWithPopup(this.auth, this.provider).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        this.router.navigate(['/', 'chat']);
        return credential;
    })
}

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

  1. Вернитесь к файлу src/app/services/chat.service.ts .
  2. Найдите функцию logout .
  3. Замените всю функцию следующим кодом.

chat.service.ts

// Logout of Friendly Chat.
logout() {
    signOut(this.auth).then(() => {
        this.router.navigate(['/', 'login'])
        console.log('signed out');
    }).catch((error) => {
        console.log('sign out error: ' + error);
    })
}

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

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

  1. Вернитесь к файлу src/app/services/chat.service.ts .
  2. Найдите назначение переменной user$ .

chat.service.ts

// observable that is updated when the auth state changes
user$ = user(this.auth);

Приведенный выше код вызывает user функции AngularFire, который возвращает наблюдаемого пользователя. Он срабатывает каждый раз, когда изменяется состояние аутентификации (когда пользователь входит в систему или выходит из системы). Компоненты шаблонов Angular в FriendlyChat используют эту наблюдаемую для обновления пользовательского интерфейса для перенаправления, отображения пользователя в заголовке навигации и т. д.

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

  1. Создайте коммит с сообщением о коммите «Добавление аутентификации Google» и отправьте его в свой репозиторий GitHub.
  2. Откройте страницу хостинга приложений в консоли Firebase и дождитесь завершения нового развертывания.
  3. В веб-приложении обновите страницу и войдите в приложение, используя кнопку входа и свою учетную запись Google. Если вы видите сообщение об ошибке с указанием auth/operation-not-allowed , убедитесь, что вы включили вход в Google в качестве поставщика аутентификации в консоли Firebase.
  4. После входа в систему должно отобразиться изображение вашего профиля и имя пользователя: angularfire-3.png

9. Напишите сообщения в Cloud Firestore.

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

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

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

688d7bc5fb662b57.png

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

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

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

  1. Вернитесь к файлу src/app/services/chat.service.ts .
  2. Найдите функцию addMessage .
  3. Замените всю функцию следующим кодом.

chat.service.ts

// Adds a text or image message to Cloud Firestore.
addMessage = async (
  textMessage: string | null,
  imageUrl: string | null,
): Promise<void | DocumentReference<DocumentData>> => {
  // ignore empty messages
  if (!textMessage && !imageUrl) {
    console.log(
      "addMessage was called without a message",
      textMessage,
      imageUrl,
    );
    return;
  }

  if (this.currentUser === null) {
    console.log("addMessage requires a signed-in user");
    return;
  }

  const message: ChatMessage = {
    name: this.currentUser.displayName,
    profilePicUrl: this.currentUser.photoURL,
    timestamp: serverTimestamp(),
    uid: this.currentUser?.uid,
  };

  textMessage && (message.text = textMessage);
  imageUrl && (message.imageUrl = imageUrl);

  try {
    const newMessageRef = await addDoc(
      collection(this.firestore, "messages"),
      message,
    );
    return newMessageRef;
  } catch (error) {
    console.error("Error writing new message to Firebase Database", error);
    return;
  }
};

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

  1. Создайте коммит с сообщением «Опубликовать новые чаты в Firestore» и отправьте его в свой репозиторий GitHub.
  2. Откройте страницу хостинга приложений в консоли Firebase и дождитесь завершения нового развертывания.
  3. Обновить дружественный чат. После входа в систему введите сообщение, например «Привет!», а затем нажмите «ОТПРАВИТЬ» . Это запишет сообщение в Cloud Firestore. Однако вы пока не увидите данные в своем реальном веб-приложении, поскольку вам все еще нужно реализовать получение данных (следующий раздел кодовой лаборатории).
  4. Вы можете увидеть новое добавленное сообщение в консоли Firebase. Откройте пользовательский интерфейс пакета эмулятора. В разделе «Сборка» нажмите «База данных Firestore» (или нажмите здесь, и вы увидите коллекцию сообщений с новым добавленным сообщением:

6812efe7da395692.png

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

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

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

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

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

chat.service.ts

// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
  // Start listening to the query.
  return collectionData(recentMessagesQuery);
}

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

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

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

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

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

angularfire-2.png

11. Добавьте функции ИИ

Вы будете использовать Google AI, чтобы добавить в приложение чата полезные вспомогательные функции.

Получите ключ Google AI API

  1. Перейдите в Google AI Studio и нажмите « Создать ключ API» .
  2. Выберите проект Firebase, который вы создали для этой лаборатории кода. Запрос предназначен для проекта Google Cloud, но каждый проект Firebase является проектом Google Cloud.
  3. Нажмите «Создать ключ API в существующем проекте».
  4. Скопируйте полученный ключ API

Установить расширение

Это расширение развернет облачную функцию, которая срабатывает каждый раз, когда новый документ добавляется в коллекцию messages в Firestore. Функция вызовет Gemini и запишет свой ответ обратно в поле response в документе.

  1. Нажмите «Установить» в консоли Firebase на странице «Создание чат-бота с расширением Gemini API» .
  2. Следуйте подсказкам. Как только вы перейдете к шагу «Настроить расширение» , установите следующие значения параметров:
    • Поставщик API Gemini: Google AI
    • Ключ Google AI API: вставьте созданный ранее ключ и нажмите « Создать секрет» .
    • Путь сбора данных Firestore: messages
    • Поле подсказки: text
    • Поле ответа: response
    • Поле заказа: timestamp
    • Контекст: Keep your answers short, informal, and helpful. Use emojis when possible.
  3. Нажмите « Установить расширение».
  4. Подождите, пока расширение завершит установку.

Тестирование функции ИИ

В FriendlyChat уже есть код для чтения ответов от расширения AI. Все, что вам нужно сделать, это отправить новое сообщение в чат, чтобы проверить его!

  1. Откройте FriendlyChat и отправьте сообщение.
  2. Через мгновение вы должны увидеть всплывающий ответ рядом с вашим сообщением. В конце есть примечание ✨ ai generated чтобы было понятно, что оно было создано с помощью генеративного ИИ, а не реального пользователя.

12. Отправьте изображения

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

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

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

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

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

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

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

чат.service.ts

// Saves a new message containing an image in Firestore.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - Add a message with a loading icon that will get updated with the shared image.
    const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
    const newImageRef = ref(this.storage, 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.
    messageRef ?
    await updateDoc(messageRef, {
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    }): null;
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

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

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

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

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

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

Добавьте сервисного работника FCM

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

Поставщик обмена сообщениями уже должен был быть настроен при добавлении AngularFire. Убедитесь, что следующий код существует в разделе импорта /angularfire-start/src/app/app.config.ts

provideMessaging(() => {
    return getMessaging();
}),

app/app.config.ts

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

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

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

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

chat.service.ts

  1. Найдите функцию saveMessagingDeviceToken .
  2. Замените всю функцию следующим кодом.

chat.service.ts

// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
    try {
      const currentToken = await getToken(this.messaging);
      if (currentToken) {
        console.log('Got FCM device token:', currentToken);
        // Saving the Device Token to Cloud Firestore.
        const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
        await setDoc(tokenRef, { uid: this.auth.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(this.messaging, (message) => {
          console.log(
            'New foreground notification from Firebase Messaging!',
            message.notification
          );
        });
      } else {
        // Need to request permissions to show notifications.
        this.requestNotificationsPermissions();
      }
    } catch(error) {
      console.error('Unable to get messaging token.', error);
    };
}

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

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

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

8b9d0c66dc36153d.png

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

chat.service.ts

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

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

  1. Создайте коммит с сообщением «Добавьте возможность публикации изображений» и отправьте его в свой репозиторий GitHub.
  2. Откройте страницу хостинга приложений в консоли Firebase и дождитесь завершения нового развертывания.
  3. Обновить дружественный чат. После входа в систему должно появиться диалоговое окно разрешения уведомлений: bd3454e6dbfb6723.png
  4. Нажмите Разрешить .
  5. Откройте консоль JavaScript вашего браузера. Вы должны увидеть следующее сообщение: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  6. Скопируйте токен вашего устройства. Он понадобится вам на следующем этапе работы над кодом.

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

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

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

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

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

de79e8638a45864c.png

14. Правила безопасности 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;
    }
  }
}

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

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

Cloud Storage for 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 МБ.

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

Storage.rules

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;
    }
  }
}

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

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

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

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

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

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

16. [Необязательно] Принудительное выполнение с помощью проверки приложений

Проверка приложений Firebase помогает защитить ваши сервисы от нежелательного трафика и защитить ваш сервер от злоупотреблений. На этом этапе вы добавите проверку учетных данных и заблокируете неавторизованных клиентов с помощью App Check и reCAPTCHA Enterprise .

Сначала вам нужно включить проверку приложений и reCaptcha.

Включение reCaptcha Enterprise

  1. В облачной консоли найдите и выберите reCaptcha Enterprise в разделе «Безопасность».
  2. Включите службу согласно запросу и нажмите « Создать ключ» .
  3. Введите отображаемое имя в соответствии с запросом и выберите Веб-сайт в качестве типа платформы.
  4. Добавьте развернутые URL-адреса в список доменов и убедитесь, что параметр «Использовать вызов флажка» не выбран .
  5. Нажмите «Создать ключ» и сохраните сгенерированный ключ где-нибудь для безопасного хранения. Он понадобится вам позже на этом этапе.

Включение проверки приложений

  1. В консоли Firebase найдите раздел «Сборка» на левой панели.
  2. Нажмите «Проверка приложений» , затем перейдите на вкладку «Метод входа» , чтобы перейти к «Проверка приложений» .
  3. Нажмите «Зарегистрировать» и при появлении запроса введите ключ reCaptcha Enterprise, затем нажмите « Сохранить» .
  4. В представлении API выберите «Хранилище» и нажмите «Применить» . Сделайте то же самое для Cloud Firestore .

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

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

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

Перейдите к файлу environment.ts и добавьте reCAPTCHAEnterpriseKey к объекту environment .

export const environment = {
  firebase: {
    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',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

Замените значение key своим токеном reCaptcha Enterprise.

Затем перейдите к файлу app.config.ts и добавьте следующий импорт:

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

В том же файле app.config.ts добавьте следующее объявление глобальной переменной:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

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

imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
  provider: new ReCaptchaEnterpriseProvider(
  environment.reCAPTCHAEnterpriseKey.key
  ),
  isTokenAutoRefreshEnabled: true,
  });
  if (location.hostname === 'localhost') {
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
  }
  return appCheck;
}),

Чтобы разрешить локальное тестирование, установите для self.FIREBASE_APPCHECK_DEBUG_TOKEN значение true . Когда вы обновляете свое приложение на localhost , в консоли регистрируется токен отладки, похожий на:

App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.

Теперь перейдите в представление « Проверка приложений» в консоли Firebase.

Нажмите на дополнительное меню и выберите «Управление токенами отладки» .

Затем нажмите «Добавить токен отладки» и вставьте токен отладки с консоли, как будет предложено.

Перейдите к файлу chat.service.ts и добавьте следующий импорт:

import { AppCheck } from '@angular/fire/app-check';

В том же файле chat.service.ts добавьте проверку приложений вместе с другими службами Firebase.

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...
  1. Создайте коммит с сообщением о фиксации «Блокировать неавторизованных клиентов с помощью проверки приложений» и отправьте его в свой репозиторий GitHub.
  2. Откройте страницу хостинга приложений в консоли Firebase и дождитесь завершения нового развертывания.

Поздравляем! Проверка приложений теперь должна работать в вашем приложении.