Лаборатория веб-кода 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 и облачное хранилище для Firebase, ваш проект Firebase должен находиться на тарифном плане с оплатой по мере использования (Blaze) , что означает, что он связан с учетной записью выставления счетов в облаке .

Чтобы обновить проект до плана 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 в вашем проекте Firebase:

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

Настройте облачное хранилище для Firebase

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

Вот как настроить Cloud Storage для Firebase в вашем проекте Firebase:

  1. На левой панели консоли Firebase разверните «Сборка» и выберите «Хранилище» .
  2. Нажмите «Начать» .
  3. Выберите расположение для сегмента хранилища по умолчанию.
    Сегменты в US-WEST1 , US-CENTRAL1 и US-EAST1 могут использовать преимущества уровня «Всегда бесплатно» для Google Cloud Storage. Во всех остальных местах сегменты соответствуют ценам и использованию Google Cloud Storage .
  4. Нажмите «Запустить в тестовом режиме» . Прочтите отказ от ответственности о правилах безопасности.
    Позже в этой лабораторной работе вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не публикуйте приложение без добавления правил безопасности для сегмента хранилища.
  5. Нажмите Создать .

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.firebasestorage.app",
    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 для 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.firebasestorage.app',
    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 и дождитесь завершения нового развертывания.

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