Гид по технологиям

Как подключить Firebase к Angular и выполнять CRUD-запросы в Firestore

7 min read Разработка Обновлено 19 Dec 2025
Firebase + Angular: CRUD в Firestore
Firebase + Angular: CRUD в Firestore

Аналитические данные из базы данных, отображённые плитками на сайте

Firebase — это платформа от Google с набором сервисов для разработки и масштабирования приложений: хостинг, хранение данных, аналитика и многое другое. В этом материале мы подробно разберём, как создать базу данных Firestore, заполнить её тестовыми записями и подключить локальное приложение на Angular для выполнения операций CRUD (Create, Read, Update, Delete).

Вспомогательные определения:

  • Firestore — документо‑ориентированная база данных от Firebase. Документы хранятся в коллекциях.
  • AngularFire — официальная библиотека для интеграции Firebase с Angular.

Содержание

  • Создание проекта Firebase и базы Firestore
  • Регистрация веб‑приложения в проекте Firebase
  • Установка и конфигурация @angular/fire в Angular
  • Сервис для работы с Firestore: примеры функций для CRUD
  • Запросы с фильтрами, сортировкой и пагинацией
  • Безопасность, правила и GDPR‑заметки
  • Отладка, типичные ошибки и как их решать
  • Альтернативы и рекомендации
  • Короткая сводка и контрольный чеклист

Как создать проект Firebase и базу данных Firestore

Если у вас уже есть аккаунт Google и рабочая среда с Angular, переходите к шагам ниже. В противном случае зарегистрируйте Google‑аккаунт и установите локально Angular CLI.

  1. Откройте консоль Firebase: в правом верхнем углу главной страницы Firebase кликните “Go to Console”.
  2. В разделе “Your Firebase projects” выберите “Add project” и следуйте диалогу создания проекта.

Страница Firebase с подсказкой создать новый проект

  1. После создания проект откроется. Слева в панели найдите блок с сервисами и наведите на иконки, пока не увидите “Firestore Database”, затем выберите его.

Страница Firebase с кнопкой создать базу данных

  1. Нажмите “Create database” и следуйте подсказкам.
  2. На этапе правил безопасности выберите “Start in test mode” для быстрого старта. В produksi‑проектах установите строгие правила доступа.

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

  1. После создания базы данных структура Firestore основана на коллекциях. Коллекция — это аналог таблицы в реляционных БД. Для примера создадим коллекцию с идентификатором “User”.

Окно создания новой коллекции в Firestore

  1. Добавьте первый документ с полями: firstName (string), lastName (string), vipMember (boolean). Document ID можно генерировать автоматически.

Окно добавления записи в коллекцию Firestore

  1. Сохраните документ и добавьте несколько тестовых записей — это пригодится для примеров запросов и фильтрации.

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

Как зарегистрировать веб‑приложение в Firebase и получить конфигурацию

  1. В консоли Firebase выберите “Project Overview”.
  2. Нажмите кнопку Web (иконка со скобками < >) чтобы зарегистрировать веб‑приложение.

Страница Firebase с формой регистрации веб‑приложения

  1. Укажите имя приложения и зарегистрируйте его.
  2. Установите Firebase в локальном проекте Angular:
npm i firebase
  1. Firebase выдаст объект конфигурации. Скопируйте эти данные в файлы окружения Angular: src/environments/environment.ts и src/environments/environment.prod.ts.

Пример содержимого environment.ts:

export const environment = {
  production: true,
  firebaseConfig: {
    apiKey: "your-api-key",
    authDomain: "your-auth-domain",
    projectId: "your-project-id",
    storageBucket: "your-storage-buckey",
    messagingSenderId: "your-messaging-sender-id",
    appId: "your-api-id",
    measurementId: "your-measurement-id"
  }
};
  1. Для интеграции с Angular используйте пакет @angular/fire. Установите его:
npm i @angular/fire

Примечание по совместимости: API и пакеты AngularFire эволюционируют между релизами. Перед установкой проверьте документацию проекта @angular/fire для версии, совместимой с используемой версией Angular.

  1. В app.module.ts импортируйте модули и инициализируйте Firebase:
import { AngularFireModule } from "@angular/fire";
import { AngularFirestoreModule } from "@angular/fire/firestore";
import { environment } from "../environments/environment";

@NgModule({
  imports: [
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFirestoreModule,
    // ... другие модули
  ],
})
export class AppModule {}

Организация сервиса для работы с Firestore

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

  1. Создайте файл src/app/services/service.ts.

  2. Подключите AngularFirestore и создайте класс сервиса:

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})
export class Service {
  constructor(private db: AngularFirestore) { }
}
  1. Пример функции, которая возвращает все записи из коллекции User как Promise:
getAllUsers() {
  return new Promise((resolve) => {
    this.db.collection('User').valueChanges({ idField: 'id' }).subscribe(users => resolve(users));
  });
}
  1. Использование сервиса в компоненте — импортируйте его и добавьте в конструктор:
import { Service } from 'src/app/services/service';

constructor(private service: Service) {}

async getUsers() {
  this.allUsers = await this.service.getAllUsers();
  console.log(this.allUsers);
}

Критерий приёмки: сервис возвращает массив объектов пользователей, каждый объект содержит поля firstName, lastName, vipMember и поле id, если оно было запрошено через idField.

Добавление новой записи в Firestore

Пример функции для добавления нового пользователя в services.ts:

addNewUser(_newId: any, _fName: string, _lName: string, _vip: boolean) {
  this.db.collection("User").doc(_newId).set({ firstName: _fName, lastName: _lName, vipMember: _vip });
}

Вызов из компонента:

this.service.addNewUser("62289836", "Jane", "Doe", true);

Совет: при генерации ID используйте UUID или авто‑генерацию документа: this.db.collection(‘User’).add({…}) — это создаст документ с уникальным ID.

Обновление данных в Firestore

Для частичного обновления используйте метод update:

updateUserFirstName(_id: any, _firstName: string) {
  this.db.doc(`User/${_id}`).update({ firstName: _firstName });
}

updateUserFullName(_id: any, _firstName: string, _lastName: string) {
  this.db.doc(`User/${_id}`).update({ firstName: _firstName, lastName: _lastName });
}

Примеры вызова:

this.service.updateUserFirstName("vLBnSegFl1pD7XQ42TBv", "Kay");
this.service.updateUserFullName("vLBnSegFl1pD7XQ42TBv", "Kay", "Jones");

Важно: update не создаёт документ, если его не существует. Для создания или перезаписи используйте set.

Удаление записи

Для удаления документа используйте delete:

deleteUser(_id: any) {
  this.db.doc(`User/${_id}`).delete();
}

Вызов из компонента:

this.service.deleteUser("vLBnSegFl1pD7XQ42TBv");

Запросы, фильтры и пагинация

Firestore поддерживает фильтрацию через where, сортировку через orderBy и ограничение через limit/startAt. Примеры:

  1. Получить всех VIP-пользователей:
getAllVipMembers() {
  return new Promise((resolve) => {
    this.db.collection('User', ref => ref.where('vipMember', '==', true)).valueChanges().subscribe(users => resolve(users));
  });
}
  1. Отсортировать VIP по фамилии (может потребоваться создание индекса в консоли Firebase):
getAllVipMembers() {
  return new Promise((resolve) => {
    this.db.collection('User', ref => ref.where('vipMember', '==', true).orderBy('lastName')).valueChanges().subscribe(users => resolve(users));
  });
}
  1. Ограничить результат первыми тремя записями (пагинация):
getAllVipMembers() {
  return new Promise((resolve) => {
    this.db.collection('User', ref => ref.where('vipMember', '==', true).orderBy('lastName').limit(3)).valueChanges().subscribe(users => resolve(users));
  });
}

Примечание по startAt: для корректного использования startAt/startAfter в сочетании с orderBy нужно передавать значение поля индексирования или документ‑снапшот.

Типичные ошибки и отладка

  • “Missing or insufficient permissions”: вероятно, правила безопасности не позволяют операцию. Проверьте Firestore Rules и авторизацию.
  • “No index available”: Firestore требует индекс для комбинированных запросов (where + orderBy). В консоли Firebase по ошибке есть ссылка для создания нужного индекса.
  • Несовместимость версий @angular/fire и Angular: проверьте сопоставление версий в документации.
  • Undefined при получении полей: убедитесь, что структура документов и поля совпадают с теми, которые вы ожидаете.

Советы по отладке:

  • Логируйте ответ valueChanges() и snapshotChanges() — snapshot даёт больше метаданных.
  • Используйте консоль Firebase для проверки структуры базы и тестовых операций.

Безопасность и приватность

Важно не оставлять правила в Test Mode в продакшене. Основные рекомендации:

  • Переведите правила безопасности на проверку аутентификации: allow read, write: if request.auth != null && условие_доступа;
  • Ограничивайте доступ по ролям (claims) или по UID пользователей;
  • Для хранения персональных данных (PII) убедитесь в соответствии с локальными законами о защите данных (GDPR/закон о персональных данных) — минимизируйте набор хранимых полей и держите доступ логированным;
  • Шифруйте конфиденциальные данные на уровне клиента или сервера, если это требуется по регламенту.

Практическая заметка: public API key, который предоставляется в firebaseConfig, не является секретом и предназначен для использования в клиентских приложениях. Секреты следует хранить на бэкенде.

Альтернативы и когда Firestore не подходит

  • Realtime Database: если вам нужны очень быстрые стримы и упрощённая модель, Realtime Database может быть проще. Однако Firestore лучше масштабируется и предлагает более мощные запросы.
  • Реляционные БД: если нужны сложные транзакции или связи уровня SQL, стоит рассмотреть PostgreSQL/MySQL.

Когда Firestore может быть не лучшим выбором:

  • Нужна сложная агрегация слоёв данных SQL (JOIN). Firestore — документо‑ориентированная модель.
  • Требуется минимальная стоимость на долгих больших объёмах «холодных» данных с редкими запросами — соотношение стоимости зависит от паттернов чтения/записи.

Ментальные модели и лучшие практики

  • Коллекции и документы вместо таблиц и строк: маленькие документы (<1 МБ) для быстрого доступа.
  • Декомпозиция данных: дублирование (денормализация) допустимо для скорости чтения; обновления нужно синхронизировать транзакциями или облачными функциями.
  • Пагинация через курсоры (startAfter/limit) лучше, чем offset, для масштабируемости.
  • Используйте snapshotChanges() для получения метаданных документа (id, exists, timestamps).

Контрольный чеклист перед релизом

  • Правила безопасности не в тестовом режиме
  • Проверены индексы Firestore для всех комплексных запросов
  • Минимизированы и защищены персональные данные
  • Обновлены зависимости @angular/fire и firebase в package.json
  • Покрыты базовые тесты для сервисов доступа к Firestore

Примеры тестовых сценариев

  1. Получение всех пользователей:
  • Действие: вызвать getAllUsers()
  • Ожидание: Promise возвращает массив с объектами пользователей, каждый объект содержит firstName, lastName
  1. Добавление и удаление пользователя:
  • Действие: вызвать addNewUser(), затем deleteUser()
  • Ожидание: после addNewUser() документ появляется в консоли Firestore; после deleteUser() документ удалён
  1. Обновление поля:
  • Действие: вызвать updateUserFirstName()
  • Ожидание: значение firstName изменено в документе

Шаблон роли: что должен сделать фронтенд‑разработчик

  • Проверить конфигурацию environment
  • Установить и инициализировать AngularFire
  • Реализовать сервисы для CRUD и покрыть их unit‑тестами
  • Подключить отображение данных в компонентах и обрабатывать состояния загрузки/ошибок

Сниппет‑шпаргалка (cheat sheet)

  • Установка:
npm i firebase @angular/fire
  • Инициализация:
AngularFireModule.initializeApp(environment.firebaseConfig);
AngularFirestoreModule;
  • Добавление (авто‑id):
this.db.collection('User').add({ firstName: 'A', lastName: 'B', vipMember: false });
  • Получение с id поля:
this.db.collection('User').valueChanges({ idField: 'id' }).subscribe(...);
  • Фильтрация и сортировка:
this.db.collection('User', ref => ref.where('vipMember', '==', true).orderBy('lastName'))

Решение выбора: Firestore или Realtime (Mermaid)

flowchart TD
  A[Нужна ли сложная фильтрация и масштабирование?] -->|Да| B[Firestore]
  A -->|Нет, важна минимальная задержка| C[Realtime Database]
  B --> D{Требуются транзакции и связи}
  D -->|Да| E[Рассмотреть реляционную БД или гибрид]
  D -->|Нет| F[Firestore подходит]

Краткая сводка

Это руководство показало пошаговый путь от создания проекта в Firebase до интеграции Firestore с Angular через @angular/fire и реализации основных операций CRUD. Также приведены рекомендации по безопасности, отладке, паттернам проектирования и альтернативам.

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

Дополнительные материалы: официальная документация Firebase и репозиторий @angular/fire на GitHub помогут уточнить детали реализации и совместимости версий.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Точная настройка курсора в Windows
Настройки мыши

Точная настройка курсора в Windows

Обзоры книг на Amazon: как писать, чтобы читали
Обзоры книг

Обзоры книг на Amazon: как писать, чтобы читали

Shortcuts на Mac: как найти, создать и автоматизировать
macOS

Shortcuts на Mac: как найти, создать и автоматизировать

Восстановление файлов после BBBW-шифровальщика
Кибербезопасность

Восстановление файлов после BBBW-шифровальщика

Как остановить сохранение файлов Windows в OneDrive
Windows

Как остановить сохранение файлов Windows в OneDrive

Перетаскивание на iPhone — Drag & Drop в iOS 15
iOS

Перетаскивание на iPhone — Drag & Drop в iOS 15