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

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

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

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

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

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

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

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

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

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

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

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

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

В этом практическом занятии используется только репозиторий 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 (в Firebase она называется "Gemini").
  6. Для этого практического занятия вам не понадобится 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. Вы можете оставить значение по умолчанию или выбрать регион, расположенный недалеко от вас.

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

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

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

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

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

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

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

Интерфейс командной строки Firebase (CLI) позволяет использовать 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 для получения Observable-массива со всеми поездками.

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

Другие методы обеспечения безопасности включают внедрение правил безопасности или использование Cloud Functions с 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 !

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

Наряду с Firebase Authentication, 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

Чтобы разрешить просмотр туристических сообщений только авторизованным пользователям, перейдите в файл 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;
		}
	}
}