Лаборатория разработки веб-фреймворков Firebase Angular

1. Что вы создадите

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

AngularFire будет использоваться для создания веб-приложения, Emulator Suite — для локального тестирования, Authentication — для отслеживания пользовательских данных, Firestore и Storage — для сохранения данных и мультимедиа на базе Cloud Functions и, наконец, Firebase Hosting — для развертывания приложения.

Чему вы научитесь

  • Как разрабатывать продукты Firebase локально с помощью Emulator Suite
  • Как улучшить ваше веб-приложение с помощью AngularFire
  • Как сохранить данные в Firestore
  • Как сохранить медиафайлы в хранилище
  • Как развернуть приложение на Firebase Hosting
  • Как использовать облачные функции для взаимодействия с базами данных и API

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

  • Node.js версии 10 или выше
  • Учетная запись Google для создания и управления вашим проектом Firebase
  • Firebase CLI версии 11.14.2 или более поздней
  • Браузер по вашему выбору, например Chrome
  • Базовое понимание Angular и Javascript

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

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

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

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

Репозиторий Github содержит примеры проектов для нескольких платформ.

В этой лабораторной работе используется только репозиторий webframework:

  • 📁 webframework : начальный код, на основе которого вы будете работать во время этой лабораторной работы.

Установка зависимостей

После клонирования установите зависимости в корневую папку и папку functions перед сборкой веб-приложения.

cd webframework && npm install
cd functions && npm install

Установить Firebase CLI

Установите Firebase CLI с помощью этой команды в терминале:

npm install -g firebase-tools

Дважды проверьте, что версия вашей Firebase CLI выше 11.14.2, используя:

firebase  --version

Если ваша версия ниже 11.14.2, выполните обновление с помощью:

npm update firebase-tools

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

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

  1. Войдите в консоль Firebase, используя свою учетную запись Google.
  2. Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например, FriendlyChat ).
  3. Нажмите «Продолжить» .
  4. При появлении соответствующего запроса ознакомьтесь с условиями Firebase и примите их, а затем нажмите кнопку «Продолжить» .
  5. (Необязательно) Включите помощь ИИ в консоли Firebase (так называемая «Gemini в Firebase»).
  6. Для этой лабораторной работы вам не понадобится Google Analytics, поэтому отключите опцию Google Analytics.
  7. Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .

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

  1. Щелкните значок Интернета, чтобы создать новое веб-приложение Firebase.
  2. На следующем шаге вы увидите объект конфигурации. Скопируйте содержимое этого объекта в файл environments/environment.ts .

Настройка продуктов Firebase

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

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

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

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

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

Чтобы включить вход через Google :

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

Включить Cloud Firestore

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

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

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

  1. В разделе «Сборка» консоли Firebase нажмите «Хранилище» .
  2. Если кнопки «Начать» нет, это означает, что облачное хранилище уже доступно.

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

  1. Нажмите «Начать» .
  2. Ознакомьтесь с отказом от ответственности о правилах безопасности для вашего проекта Firebase, затем нажмите кнопку Далее .
  3. Расположение облачного хранилища предварительно выбрано в том же регионе, что и для базы данных Cloud Firestore. Нажмите «Готово» , чтобы завершить настройку.

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

4. Подключитесь к своему проекту Firebase

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

Убедитесь, что ваша командная строка обращается к локальному каталогу webframework вашего приложения.

Подключите код веб-приложения к вашему проекту Firebase. Сначала войдите в Firebase CLI через командную строку:

firebase login

Затем выполните следующую команду, чтобы создать псевдоним проекта. Замените $YOUR_PROJECT_ID на идентификатор вашего проекта Firebase.

firebase  use  $YOUR_PROJECT_ID

Добавить AngularFire

Чтобы добавить AngularFire в приложение, выполните команду:

ng add @angular/fire

Затем следуйте инструкциям командной строки и выберите функции, которые существуют в вашем проекте Firebase.

Инициализировать Firebase

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

firebase init

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

Запустить эмуляторы

Из каталога webframework выполните следующую команду для запуска эмуляторов:

firebase  emulators:start

В конечном итоге вы должны увидеть что-то вроде этого:

$  firebase  emulators:start

i  emulators:  Starting  emulators:  auth,  functions,  firestore,  hosting,  functions

i  firestore:  Firestore  Emulator  logging  to  firestore-debug.log

i  hosting:  Serving  hosting  files  from:  public

  hosting:  Local  server:  http://localhost:5000

i  ui:  Emulator  UI  logging  to  ui-debug.log

i  functions:  Watching  "/functions"  for  Cloud  Functions...

  functions[updateMap]:  firestore  function  initialized.

  

┌─────────────────────────────────────────────────────────────┐

    All  emulators  ready!  It  is  now  safe  to  connect  your  app.  

  i  View  Emulator  UI  at  http://localhost:4000  

└─────────────────────────────────────────────────────────────┘

  

┌────────────────┬────────────────┬─────────────────────────────────┐

  Emulator    Host:Port    View  in  Emulator  UI  

├────────────────┼────────────────┼─────────────────────────────────┤

  Authentication    localhost:9099    http://localhost:4000/auth  

├────────────────┼────────────────┼─────────────────────────────────┤

  Functions    localhost:5001    http://localhost:4000/functions  

├────────────────┼────────────────┼─────────────────────────────────┤

  Firestore    localhost:8080    http://localhost:4000/firestore  

├────────────────┼────────────────┼─────────────────────────────────┤

  Hosting    localhost:5000    n/a  

└────────────────┴────────────────┴─────────────────────────────────┘

Emulator  Hub  running  at  localhost:4400

Other  reserved  ports:  4500

  

Issues?  Report  them  at  https://github.com/firebase/firebase-tools/issues  and  attach  the  *-debug.log  files.

Как только вы увидите сообщение ✔All emulators ready! эмуляторы готовы к использованию.

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

А теперь приступим к строительству!

5. Подключите веб-приложение к эмуляторам.

Согласно таблице в журналах эмулятора, эмулятор Cloud Firestore прослушивает порт 8080, а эмулятор аутентификации прослушивает порт 9099.

Откройте EmulatorUI

В веб-браузере перейдите по адресу http://127.0.0.1:4000/ . Вы увидите интерфейс Emulator Suite.

Направьте приложение на использование эмуляторов

В src/app/app.module.ts добавьте следующий код в список импорта AppModule :

@NgModule({
	declarations: [...],
	imports: [
		provideFirebaseApp(() =>  initializeApp(environment.firebase)),

		provideAuth(() => {
			const  auth = getAuth();
			if (location.hostname === 'localhost') {
				connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings:  true });
			}
			return  auth;
		}),

		provideFirestore(() => {
			const  firestore = getFirestore();
			if (location.hostname === 'localhost') {
				connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
			}
			return  firestore;
		}),

		provideFunctions(() => {
			const  functions = getFunctions();
			if (location.hostname === 'localhost') {
				connectFunctionsEmulator(functions, '127.0.0.1', 5001);
			}
			return  functions;
		}),

		provideStorage(() => {
			const  storage = getStorage();
			if (location.hostname === 'localhost') {
				connectStorageEmulator(storage, '127.0.0.1', 5001);
			}
			return  storage;
		}),
		...
	]

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

6. Добавление аутентификации

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

Для этого мы можем импортировать функции signin напрямую из AngularFire и отслеживать состояние авторизации пользователя с помощью функции authState . Измените функции страницы входа так, чтобы она проверяла состояние авторизации пользователя при загрузке.

Внедрение аутентификации AngularFire

В файле src/app/pages/login-page/login-page.component.ts импортируйте Auth из @angular/fire/auth и внедрите его в LoginPageComponent . Поставщики аутентификации, такие как Google, и функции, такие как signin signout , также можно напрямую импортировать из того же пакета и использовать в приложении.

import { Auth, GoogleAuthProvider, signInWithPopup, signOut, user } from  '@angular/fire/auth';

export  class  LoginPageComponent  implements  OnInit {
	private  auth: Auth = inject(Auth);
	private  provider = new  GoogleAuthProvider();
	user$ = user(this.auth);
	constructor() {}  

	ngOnInit(): void {} 

	login() {
		signInWithPopup(this.auth, this.provider).then((result) => {
			const  credential = GoogleAuthProvider.credentialFromResult(result);
			return  credential;
		})
	}

	logout() {
		signOut(this.auth).then(() => {
			console.log('signed out');}).catch((error) => {
				console.log('sign out error: ' + error);
		})
	}
}

Теперь страница входа работает! Попробуйте войти и проверьте результаты в эмуляторе аутентификации.

7. Настройка Firestore

На этом этапе вы добавите функционал для публикации и обновления записей в блоге о путешествиях, хранящихся в Firestore.

Подобно аутентификации, функции Firestore поставляются в виде предустановленных функций AngularFire. Каждый документ принадлежит коллекции, и каждый документ может иметь вложенные коллекции. Для создания и обновления записи в блоге о путешествиях необходимо знать path к документу в Firestore.

Реализация TravelService

Поскольку многим различным страницам необходимо будет читать и обновлять документы Firestore в веб-приложении, мы можем реализовать функции в src/app/services/travel.service.ts , чтобы избежать многократного внедрения одних и тех же функций AngularFire на каждую страницу.

Начнём с внедрения Auth , аналогично предыдущему шагу, а также Firestore в наш сервис. Также полезно определить наблюдаемый объект user$ , который отслеживает текущий статус аутентификации.

import { doc, docData, DocumentReference, Firestore, getDoc, setDoc, updateDoc, collection, addDoc, deleteDoc, collectionData, Timestamp } from  "@angular/fire/firestore";

export  class  TravelService {
	firestore: Firestore = inject(Firestore);
	auth: Auth = inject(Auth);
	user$ = authState(this.auth).pipe(filter(user  =>  user !== null), map(user  =>  user!));
	router: Router = inject(Router);

Добавление поста о путешествии

Записи о путешествиях будут существовать в виде документов, хранящихся в Firestore. Поскольку документы должны находиться в коллекциях, коллекция, содержащая все записи о путешествиях, будет называться travels . Таким образом, путь к любой записи о путешествиях будет travels/

Используя функцию addDoc из AngularFire, объект можно вставить в коллекцию:

async  addEmptyTravel(userId: String) {
	...
	addDoc(collection(this.firestore, 'travels'), travelData).then((travelRef) => {
		collection(this.firestore, `travels/${travelRef.id}/stops`);
		setDoc(travelRef, {... travelData, id:  travelRef.id})
		this.router.navigate(['edit', `${travelRef.id}`]);
		return  travelRef;

	})
}

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

Учитывая uid любого туристического поста, можно вывести путь к документу, хранящемуся в Firestore, который затем можно прочитать, обновить или удалить с помощью функций updateFoc и deleteDoc AngularFire:

async  updateData(path: string, data: Partial<Travel | Stop>) {
	await  updateDoc(doc(this.firestore, path), data)
}

async  deleteData(path: string) {
	const  ref = doc(this.firestore, path);
	await  deleteDoc(ref)
}

Чтение данных как наблюдаемого

Поскольку путевые заметки и остановки по пути можно изменять после создания, было бы полезнее получать объекты документа как наблюдаемые, чтобы подписываться на любые изменения. Эта функциональность предоставляется функциями docData и collectionData из @angular/fire/firestore .

getDocData(path: string) {
	return  docData(doc(this.firestore, path), {idField:  'id'}) as  Observable<Travel | Stop>
}

  
getCollectionData(path: string) {
	return  collectionData(collection(this.firestore, path), {idField:  'id'}) as  Observable<Travel[] | Stop[]>
}

Добавление остановок в туристический пост

Теперь, когда работа постов о путешествиях налажена, пришло время рассмотреть остановки, которые будут находиться в подгруппе постов о путешествиях, например: travels/ /stops/

Это почти идентично созданию поста о путешествии, поэтому поставьте себе задачу реализовать это самостоятельно или ознакомьтесь с реализацией ниже:

async  addStop(travelId: string) {
	...
	const  ref = await  addDoc(collection(this.firestore, `travels/${travelId}/stops`), stopData)
	setDoc(ref, {...stopData, id:  ref.id})
}

Отлично! Функции Firestore были реализованы в сервисе Travel, так что теперь вы можете увидеть их в действии.

Использование функций Firestore в приложении

Перейдите в src/app/pages/my-travels/my-travels.component.ts и внедрите TravelService для использования его функций.

travelService = inject(TravelService);
travelsData$: Observable<Travel[]>;
stopsList$!: Observable<Stop[]>;
constructor() {
	this.travelsData$ = this.travelService.getCollectionData(`travels`) as  Observable<Travel[]>
}

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

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

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

Затем просто вызовите функции, реализованные в TravelService .

async  createTravel(userId: String) {
	this.travelService.addEmptyTravel(userId);
}

deleteTravel(travelId: String) {
	this.travelService.deleteData(`travels/${travelId}`)
}

Теперь страница «Мои путешествия» должна работать! Посмотрите, что происходит в эмуляторе Firestore при создании новой записи о путешествии.

Затем повторите для функций обновления в /src/app/pages/edit-travels/edit-travels.component.ts :

travelService: TravelService = inject(TravelService)
travelId = this.activatedRoute.snapshot.paramMap.get('travelId');
travelData$: Observable<Travel>;
stopsData$: Observable<Stop[]>;

constructor() {
	this.travelData$ = this.travelService.getDocData(`travels/${this.travelId}`) as  Observable<Travel>
	this.stopsData$ = this.travelService.getCollectionData(`travels/${this.travelId}/stops`) as  Observable<Stop[]>
}

updateCurrentTravel(travel: Partial<Travel>) {
	this.travelService.updateData(`travels${this.travelId}`, travel)
}

  

updateCurrentStop(stop: Partial<Stop>) {
	stop.type = stop.type?.toString();
	this.travelService.updateData(`travels${this.travelId}/stops/${stop.id}`, stop)
}

  

addStop() {
	if (!this.travelId) return;
	this.travelService.addStop(this.travelId);
}

deleteStop(stopId: string) {
	if (!this.travelId || !stopId) {
		return;
	}
	this.travelService.deleteData(`travels${this.travelId}/stops/${stopId}`)
	this.stopsData$ = this.travelService.getCollectionData(`travels${this.travelId}/stops`) as  Observable<Stop[]>

}

8. Настройка хранилища

Теперь вы реализуете хранилище для хранения изображений и других типов медиафайлов.

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

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

Давайте реализуем функции в TraveService :

Загрузка файла

Перейдите в src/app/services/travel.service.ts и внедрите Storage из AngularFire:

export  class  TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
storage: Storage = inject(Storage);

И реализуем функцию загрузки:

async  uploadToStorage(path: string, input: HTMLInputElement, contentType: any) {
	if (!input.files) return  null
	const  files: FileList = input.files;
		for (let  i = 0; i  <  files.length; i++) {
			const  file = files.item(i);
			if (file) {
				const  imagePath = `${path}/${file.name}`
				const  storageRef = ref(this.storage, imagePath);
				await  uploadBytesResumable(storageRef, file, contentType);
				return  await  getDownloadURL(storageRef);
			}
		}
	return  null;
}

Основное различие между доступом к документам из Firestore и файлам из Cloud Storage заключается в том, что, хотя оба они следуют путям, структурированным по папкам, базовый URL-адрес и комбинация пути получаются через getDownloadURL , которые затем можно сохранить и использовать в файл.

Использование функции в приложении

Перейдите к src/app/components/edit-stop/edit-stop.component.ts и вызовите функцию загрузки с помощью:

	async  uploadFile(file: HTMLInputElement, stop: Partial<Stop>) {
	const  path = `/travels/${this.travelId}/stops/${stop.id}`
	const  url = await  this.travelService.uploadToStorage(path, file, {contentType:  'image/png'});
	stop.image = url ? url : '';
	this.travelService.updateData(path, stop);
}

При загрузке изображения сам медиа-файл будет загружен в хранилище, а URL-адрес соответствующим образом сохранится в документе в Firestore.

9. Развертывание приложения

Теперь мы готовы к развертыванию приложения!

Скопируйте конфигурации firebase из src/environments/environment.ts в src/environments/environment.prod.ts и запустите:

firebase deploy

Вы должны увидеть что-то вроде этого:

 Browser application bundle generation complete.
 Copying assets complete.
 Index html generation complete.

=== Deploying to 'friendly-travels-b6a4b'...

i  deploying storage, firestore, hosting
i  firebase.storage: checking storage.rules for compilation errors...
  firebase.storage: rules file storage.rules compiled successfully
i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
  cloud.firestore: rules file firestore.rules compiled successfully
i  storage: latest version of storage.rules already up to date, skipping upload...
i  firestore: deploying indexes...
i  firestore: latest version of firestore.rules already up to date, skipping upload...
  firestore: deployed indexes in firestore.indexes.json successfully for (default) database
i  hosting[friendly-travels-b6a4b]: beginning deploy...
i  hosting[friendly-travels-b6a4b]: found 6 files in .firebase/friendly-travels-b6a4b/hosting
  hosting[friendly-travels-b6a4b]: file upload complete
  storage: released rules storage.rules to firebase.storage
  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendly-travels-b6a4b]: finalizing version...
  hosting[friendly-travels-b6a4b]: version finalized
i  hosting[friendly-travels-b6a4b]: releasing new version...
  hosting[friendly-travels-b6a4b]: release complete

  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendly-travels-b6a4b/overview
Hosting URL: https://friendly-travels-b6a4b.web.app

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

Теперь ваше приложение готово и развёрнуто на Firebase Hosting! Все данные и аналитика будут доступны в вашей консоли Firebase.

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

11. Дополнительно: аутентификационные защитные функции AngularFire

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

В src/app/app-routing.module.ts импортируйте

import {AuthGuard, redirectLoggedInTo, redirectUnauthorizedTo} from  '@angular/fire/auth-guard'

Затем вы можете определить функции, определяющие, когда и куда следует перенаправлять пользователей на определенных страницах:

const  redirectUnauthorizedToLogin = () =>  redirectUnauthorizedTo(['signin']);
const  redirectLoggedInToTravels = () =>  redirectLoggedInTo(['my-travels']);

Затем просто добавьте их в свои маршруты:

const  routes: Routes = [
	{path:  '', component:  LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectLoggedInToTravels}},
	{path:  'signin', component:  LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectLoggedInToTravels}},
	{path:  'my-travels', component:  MyTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectUnauthorizedToLogin}},
	{path:  'edit/:travelId', component:  EditTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectUnauthorizedToLogin}},
];

12. Дополнительно: правила безопасности

И Firestore, и Cloud Storage используют правила безопасности ( firestore.rules и security.rules соответственно) для обеспечения безопасности и проверки данных.

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

Правила пожарной безопасности

Чтобы разрешить просматривать записи о путешествиях только аутентифицированным пользователям, перейдите в файл firestore.rules и добавьте:

rules_version  =  '2';
service  cloud.firestore  {
	match  /databases/{database}/travels  {
		allow  read:  if  request.auth.uid  !=  null;
		allow  write:
		if  request.auth.uid  ==  request.resource.data.userId;
	}
}

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

rules_version  =  '2';
service  cloud.firestore  {
	match  /databases/{database}/posts  {
		allow  read:  if  request.auth.uid  !=  null;
		allow  write:
		if  request.auth.uid  ==  request.resource.data.userId;
		&&  "author"  in  request.resource.data
		&&  "text"  in  request.resource.data
		&&  "timestamp"  in  request.resource.data;
	}
}

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

Аналогичным образом, мы можем использовать правила безопасности для обеспечения доступа к базам данных хранилища в storage.rules . Обратите внимание, что мы также можем использовать функции для более сложных проверок:

rules_version  =  '2';

function  isImageBelowMaxSize(maxSizeMB)  {
	return  request.resource.size  <  maxSizeMB  *  1024  *  1024
		&&  request.resource.contentType.matches('image/.*');
}

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