Laboratorio de código de marcos web angulares de Firebase

1. Qué crearás

En este codelab, creará un blog itinerante con un mapa colaborativo en tiempo real con lo último de nuestra biblioteca Angular: AngularFire . La aplicación web final consistirá en un blog de viajes donde podrás subir imágenes de cada lugar al que hayas viajado.

AngularFire se utilizará para crear la aplicación web, Emulator Suite para pruebas locales, Autenticación para realizar un seguimiento de los datos del usuario, Firestore y Storage para conservar datos y medios, con tecnología de Cloud Functions y, finalmente, Firebase Hosting para implementar la aplicación.

lo que aprenderás

  • Cómo desarrollar con productos Firebase localmente con Emulator Suite
  • Cómo mejorar su aplicación web con AngularFire
  • Cómo conservar tus datos en Firestore
  • Cómo persistir los medios en el almacenamiento
  • Cómo implementar su aplicación en Firebase Hosting
  • Cómo utilizar Cloud Functions para interactuar con sus bases de datos y API

Lo que necesitarás

  • Node.js versión 10 o superior
  • Una cuenta de Google para la creación y gestión de tu proyecto Firebase
  • Firebase CLI versión 11.14.2 o posterior
  • Un navegador de tu elección, como Chrome
  • Conocimientos básicos de Angular y Javascript.

2. Obtenga el código de muestra

Clona el repositorio GitHub del codelab desde la línea de comando:

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

Alternativamente, si no tienes git instalado, puedes descargar el repositorio como un archivo ZIP .

El repositorio de Github contiene proyectos de muestra para múltiples plataformas.

Este codelab solo utiliza el repositorio de webframework:

  • 📁 webframework : el código inicial que desarrollarás durante este codelab.

Instalar dependencias

Después de la clonación, instale las dependencias en la carpeta raíz y functions antes de crear la aplicación web.

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

Instalar Firebase CLI

Instale Firebase CLI usando este comando en una terminal:

npm install -g firebase-tools

Verifique que su versión de Firebase CLI sea superior a 11.14.2 usando:

firebase  --version

Si su versión es inferior a 11.14.2, actualice usando:

npm update firebase-tools

3. Crea y configura un proyecto de Firebase

Crear un proyecto de Firebase

  1. Inicia sesión en Firebase .
  2. En Firebase console, haz clic en Agregar proyecto y luego nombra tu proyecto de Firebase <tu-proyecto> . Recuerde el ID del proyecto de su proyecto de Firebase.
  3. Haga clic en Crear proyecto .

Importante : su proyecto de Firebase se llamará <your-project> , pero Firebase le asignará automáticamente un ID de proyecto único con el formato <your-project>-1234 . Este identificador único es la forma en que realmente se identifica su proyecto (incluso en la CLI), mientras que <su-proyecto> es simplemente un nombre para mostrar.

La aplicación que vamos a crear utiliza productos de Firebase que están disponibles para aplicaciones web:

  • Autenticación de Firebase para permitir que sus usuarios inicien sesión fácilmente en su aplicación.
  • Cloud Firestore para guardar datos estructurados en la nube y recibir notificaciones instantáneas cuando los datos cambian.
  • Cloud Storage para Firebase para guardar archivos en la nube.
  • Firebase Hosting para alojar y servir sus activos.
  • Funciones para interactuar con API internas y externas.

Algunos de estos productos necesitan configuraciones especiales o deben habilitarse mediante Firebase console.

Agregar una aplicación web de Firebase al proyecto

  1. Haga clic en el ícono web para crear una nueva aplicación web de Firebase.
  2. En el siguiente paso, verá un objeto de configuración. Copie el contenido de este objeto en el archivo environments/environment.ts .

Habilite el inicio de sesión de Google para la autenticación de Firebase

Para permitir que los usuarios inicien sesión en la aplicación web con sus cuentas de Google, utilizaremos el método de inicio de sesión de Google .

Para habilitar el inicio de sesión de Google :

  1. En la consola de Firebase, ubique la sección Construir en el panel izquierdo.
  2. Haga clic en Autenticación y luego haga clic en la pestaña Método de inicio de sesión (o haga clic aquí para ir directamente allí).
  3. Habilite el proveedor de inicio de sesión de Google y luego haga clic en Guardar .
  4. Establezca el nombre público de su aplicación en <nombre-de-su-proyecto> y elija un correo electrónico de soporte del proyecto en el menú desplegable.

Habilitar Cloud Firestore

  1. En la sección Generar de Firebase console, haz clic en Base de datos de Firestore .
  2. Haga clic en Crear base de datos en el panel de Cloud Firestore.
  3. Establezca la ubicación donde se almacenan sus datos de Cloud Firestore. Puede dejar esto como predeterminado o elegir una región cercana a usted.

Habilitar almacenamiento en la nube

La aplicación web utiliza Cloud Storage para Firebase para almacenar, cargar y compartir imágenes.

  1. En la sección Compilación de Firebase console, haz clic en Almacenamiento .
  2. Si no hay ningún botón Comenzar , significa que el almacenamiento en la nube ya está

habilitado y no necesita seguir los pasos a continuación.

  1. Haga clic en Comenzar .
  2. Lea el descargo de responsabilidad sobre las reglas de seguridad para su proyecto de Firebase y luego haga clic en Siguiente .
  3. La ubicación de Cloud Storage está preseleccionada con la misma región que eligió para su base de datos de Cloud Firestore. Haga clic en Listo para completar la configuración.

Con las reglas de seguridad predeterminadas, cualquier usuario autenticado puede escribir cualquier cosa en Cloud Storage. Haremos que nuestro almacenamiento sea más seguro más adelante en este codelab.

4. Conéctese a su proyecto de Firebase

La interfaz de línea de comandos (CLI) de Firebase le permite usar Firebase Hosting para servir su aplicación web localmente, así como para implementar su aplicación web en su proyecto de Firebase.

Asegúrese de que su línea de comando acceda al directorio webframework local de su aplicación.

Conecte el código de la aplicación web a su proyecto de Firebase. Primero, inicie sesión en Firebase CLI en la línea de comando:

firebase login

Luego ejecute el siguiente comando para crear un alias de proyecto. Reemplace $YOUR_PROJECT_ID con el ID de su proyecto de Firebase.

firebase  use  $YOUR_PROJECT_ID

Agregar fuego angular

Para agregar AngularFire a la aplicación, ejecute el comando:

ng add @angular/fire

Luego, siga las instrucciones de la línea de comando y seleccione las funciones que existen en su proyecto de Firebase.

Inicializar base de fuego

Para inicializar el proyecto de Firebase, ejecute:

firebase init

Luego, siguiendo las indicaciones de la línea de comando, seleccione las funciones y los emuladores que se utilizaron en su proyecto de Firebase.

Iniciar los emuladores

Desde el directorio webframework , ejecute el siguiente comando para iniciar los emuladores:

firebase  emulators:start

Al final deberías ver algo como esto:

$  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.

Una vez que veas el ✔All emulators ready! mensaje, los emuladores están listos para usar.

Deberías ver la interfaz de usuario de tu aplicación de viajes, que (¡todavía!) no funciona:

¡Ahora comencemos a construir!

5. Conecte la aplicación web a los emuladores.

Según la tabla en los registros del emulador, el emulador de Cloud Firestore escucha en el puerto 8080 y el emulador de autenticación escucha en el puerto 9099.

Abra la interfaz de usuario del emulador

En su navegador web, navegue hasta http://127.0.0.1:4000/ . Deberías ver la interfaz de usuario de Emulator Suite.

Dirija la aplicación para usar los emuladores.

En src/app/app.module.ts , agregue el siguiente código a la lista de importaciones de 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;
		}),
		...
	]

La aplicación ahora está configurada para usar emuladores locales, lo que permite realizar pruebas y desarrollo localmente.

6. Agregar autenticación

Ahora que los emuladores están configurados para la aplicación, podemos agregar funciones de autenticación para garantizar que cada usuario haya iniciado sesión antes de publicar mensajes.

Para hacerlo, podemos importar funciones signin directamente desde AngularFire y rastrear el estado de autenticación de su usuario con la función authState . Modifique las funciones de la página de inicio de sesión para que la página verifique el estado de autenticación del usuario al cargar.

Inyectar autenticación AngularFire

En src/app/pages/login-page/login-page.component.ts , importe Auth desde @angular/fire/auth e inyéctelo en LoginPageComponent . Los proveedores de autenticación, como Google, y funciones como signin y signout también se pueden importar directamente desde el mismo paquete y usarse en la aplicación.

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

¡Ahora la página de inicio de sesión está funcional! Intente iniciar sesión y consulte los resultados en el Emulador de autenticación.

7. Configurando Firestore

En este paso, agregará funcionalidad para publicar y actualizar publicaciones de blogs de viajes almacenadas en Firestore.

Al igual que la autenticación, las funciones de Firestore vienen empaquetadas desde AngularFire. Cada documento pertenece a una colección y cada documento también puede tener colecciones anidadas. Es necesario conocer la path del documento en Firestore para crear y actualizar una publicación de blog de viajes.

Implementación de TravelService

Dado que muchas páginas diferentes necesitarán leer y actualizar documentos de Firestore en la aplicación web, podemos implementar las funciones en src/app/services/travel.service.ts , para abstenernos de inyectar repetidamente las mismas funciones de AngularFire en cada página.

Comience inyectando Auth , similar al paso anterior, así como Firestore en nuestro servicio. También es útil definir un objeto user$ observable que escuche el estado de autenticación actual.

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

Agregar una publicación de viaje

Las publicaciones de viajes existirán como documentos almacenados en Firestore y, dado que los documentos deben existir dentro de las colecciones, la colección que contiene todas las publicaciones de viajes se denominará travels . Por lo tanto, la ruta de cualquier puesto de viaje será travels/

Usando la función addDoc de AngularFire, se puede insertar un objeto en una colección:

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;

	})
}

Actualizar y eliminar datos

Dado el uid de cualquier publicación de viaje, se puede deducir la ruta del documento almacenado en Firestore, que luego se puede leer, actualizar o eliminar usando las funciones updateFoc y deleteDoc de 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)
}

Leer datos como observables

Dado que las publicaciones de viaje y las paradas en el camino se pueden modificar después de la creación, sería más útil obtener objetos de documento como observables para suscribirse a cualquier cambio que se realice. Esta funcionalidad la ofrecen las funciones docData y collectionData de @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[]>
}

Agregar paradas a una publicación de viaje

Ahora que las operaciones de la publicación de viajes están configuradas, es hora de considerar las paradas, que existirán en una subcolección de una publicación de viajes como esta: travels/ /stops/ travels/ /stops/

Esto es casi idéntico a crear una publicación de viajes, así que desafíate a implementarlo por tu cuenta o consulta la implementación a continuación:

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

¡Lindo! Las funciones de Firestore se implementaron en el servicio de Viajes, por lo que ahora puedes verlas en acción.

Usar las funciones de Firestore en la aplicación

Navegue a src/app/pages/my-travels/my-travels.component.ts e inyecte TravelService para usar sus funciones.

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

Se llama a TravelService en el constructor para obtener una matriz observable de todos los viajes.

En el caso de que solo se necesiten los viajes del usuario actual, utilice la función query .

Otros métodos para garantizar la seguridad incluyen la implementación de reglas de seguridad o el uso de Cloud Functions con Firestore, como se explora en los pasos opcionales a continuación.

Luego, simplemente llame a las funciones implementadas en TravelService .

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

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

¡Ahora la página Mis viajes debería estar funcional! Mira lo que sucede en tu emulador de Firestore cuando creas una nueva publicación de viaje.

Luego, repita para las funciones de actualización en /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. Configurar el almacenamiento

Ahora implementará Almacenamiento para almacenar imágenes y otros tipos de medios.

Cloud Firestore se utiliza mejor para almacenar datos estructurados, como objetos JSON. Cloud Storage está diseñado para almacenar archivos o blobs. En esta aplicación, la utilizará para permitir a los usuarios compartir sus fotografías de viajes.

Del mismo modo, con Firestore, almacenar y actualizar archivos con Storage requiere un identificador único para cada archivo.

Implementemos las funciones en TraveService :

Subiendo un archivo

Navegue a src/app/services/travel.service.ts e inyecte Almacenamiento desde AngularFire:

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

E implemente la función de carga:

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

La principal diferencia entre acceder a documentos desde Firestore y archivos desde Cloud Storage es que, aunque ambos siguen rutas estructuradas de carpetas, la combinación de URL base y ruta se obtiene a través de getDownloadURL , que luego se puede almacenar y usar en un archivo.

Usando la función en la aplicación

Navegue a src/app/components/edit-stop/edit-stop.component.ts y llame a la función de carga usando:

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

Cuando se carga la imagen, el archivo multimedia en sí se cargará en el almacenamiento y la URL se almacenará en consecuencia en el documento en Firestore.

9. Implementación de la aplicación

¡Ahora estamos listos para implementar la aplicación!

Copie las configuraciones firebase de src/environments/environment.ts a src/environments/environment.prod.ts y ejecute:

firebase deploy

Debería ver algo como esto:

✔ 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. ¡Felicitaciones!

¡Ahora su aplicación debería estar completa e implementada en Firebase Hosting! Todos los datos y análisis ahora estarán accesibles en su Firebase Console.

Para obtener más funciones relacionadas con AngularFire, funciones y reglas de seguridad, no olvide consultar los pasos opcionales a continuación, así como otros Firebase Codelabs .

11. Opcional: guardias de autenticación de AngularFire

Junto con Firebase Authentication, AngularFire también ofrece protecciones basadas en autenticación en rutas, para que los usuarios con acceso insuficiente puedan ser redirigidos. Esto ayuda a proteger la aplicación contra el acceso de los usuarios a datos protegidos.

En src/app/app-routing.module.ts , importe

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

Luego puede definir funciones sobre cuándo y dónde se debe redirigir a los usuarios en determinadas páginas:

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

Luego simplemente agrégalos a tus rutas:

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. Opcional: reglas de seguridad

Tanto Firestore como Cloud Storage utilizan reglas de seguridad ( firestore.rules y security.rules respectivamente) para hacer cumplir la seguridad y validar los datos.

Por el momento, los datos de Firestore y Storage tienen acceso abierto para lecturas y escrituras, ¡pero no quieres que la gente cambie las publicaciones de otros! Puede utilizar reglas de seguridad para restringir el acceso a sus colecciones y documentos.

Reglas del almacén de bomberos

Para permitir que solo los usuarios autenticados vean publicaciones de viajes, vaya al archivo firestore.rules y agregue:

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

También se pueden utilizar reglas de seguridad para validar datos:

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

Reglas de almacenamiento

De manera similar, podemos usar reglas de seguridad para imponer el acceso a las bases de datos de almacenamiento en storage.rules . Tenga en cuenta que también podemos usar funciones para comprobaciones más complejas:

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