Firebase comenzará a ser compatible con
Terraform.
Si perteneces a un equipo que desea automatizar y estandarizar la creación de proyectos de
Firebase con recursos específicos aprovisionados y servicios habilitados,
usar Terraform con Firebase es una buena opción para ti.
El flujo de trabajo básico para usar Terraform con Firebase incluye las siguientes tareas:
Crear y personalizar un archivo de configuración de Terraform (un archivo .tf) que
especifique la infraestructura que deseas aprovisionar (es decir, los recursos que
deseas aprovisionar y los servicios que deseas habilitar)
Usar comandos de gcloud CLI que interactúan con Terraform para
aprovisionar la infraestructura especificada en el archivo .tf
Borrar y modificar la infraestructura existente con Terraform
Administrar parámetros de configuración y tareas específicas de productos con Terraform, como en los siguientes ejemplos:
Habilitar los proveedores de acceso de Firebase Authentication
Crear buckets de Cloud Storage o instancias de bases de datos y, luego, implementar
reglas de seguridad de Firebase para ellos
Puedes usar comandos y archivos de configuración estándar de Terraform para realizar todas estas
tareas. A fin de ayudarte con esto, proporcionamos
archivos de configuración de Terraform de muestra para varios casos de
uso comunes.
Flujo de trabajo generalizado para usar Terraform con Firebase
Requisitos previos
Esta guía es una introducción al uso de Terraform con Firebase, por lo que se supone que tienes
conocimientos básicos sobre Terraform. Asegúrate de que cumples con los siguientes
requisitos previos antes de comenzar este flujo de trabajo.
Instala Terraform
y familiarízate con él mediante sus instructivos oficiales.
Consulta los requisitos para las cuentas de usuario y de servicio
Si usas una cuenta de usuario, debes aceptar las Condiciones del Servicio de
Firebase. Aceptaste las Condiciones del Servicio de Firebase si puedes ver
un proyecto de Firebase en
Firebase console.
Para que Terraform realice ciertas acciones (por ejemplo, crear proyectos),
se deben cumplir los siguientes requisitos:
El usuario o la cuenta de servicio deben tener acceso de IAM aplicable para
esas acciones.
Si el usuario o la cuenta de servicio forman parte de una organización de Google Cloud,
las políticas de la organización deben permitir que la cuenta realice esas acciones.
Paso 1: Crea y personaliza un archivo de configuración de Terraform
Un archivo de configuración de Terraform necesita dos secciones principales (que se describen en detalle
a continuación):
Se requiere una configuración de provider, sin importar los productos o servicios de Firebase que
participen.
Crea un archivo de configuración de Terraform (como main.tf) en el directorio
local.
En esta guía, usarás este archivo de configuración para especificar la configuración de provider
y toda la infraestructura que deseas que cree Terraform. Sin embargo,
ten en cuenta que tienes opciones para incluir la configuración del proveedor.
Consulta las opciones para
incluir la configuración de provider
Tienes las siguientes opciones para incluir una configuración de provider en
el resto de la configuración de Terraform:
Opción 1: Inclúyela en la parte superior de un solo archivo de
configuración .tf de Terraform (como se muestra en esta guía).
Usa esta opción si recién comienzas a usar Terraform o
estás probando Terraform con Firebase.
Opción 2: Inclúyela en un archivo .tf independiente (como un archivo
provider.tf), además del archivo .tf, en el que especificas la infraestructura que se
creará (como un archivo main.tf).
Usa esta opción si formas parte de un equipo más grande que necesita
estandarizar la configuración.
Cuando se ejecutan comandos de Terraform, el archivo provider.tf y el
archivo main.tf deben estar en el mismo directorio.
Incluye la siguiente configuración de provider en la parte superior del archivo main.tf.
Debes usar el proveedor google-beta porque esta es una versión beta de
cómo usar Firebase con Terraform. Ten cuidado cuando lo uses en producción.
# Terraform configuration to set up providers by version.
terraform {
required_providers {
google-beta = {
source = "hashicorp/google-beta"
version = "~> 4.0"
}
}
}
# Configures the provider to use the resource block's specified project for quota checks.
provider "google-beta" {
user_project_override = true
}
# Configures the provider to not use the resource block's specified project for quota checks.
# This provider should only be used during project creation and initializing services.
provider "google-beta" {
alias = "no_user_project_override"
user_project_override = false
}
Continúa con la siguiente sección para completar el archivo de configuración y especificar qué
infraestructura crear.
Especifica qué infraestructura crear con bloques resource
En tu archivo de configuración de Terraform (para esta guía, tu archivo main.tf), debes especificar
toda la infraestructura que deseas que Terraform cree (es decir, todos los
recursos que deseas aprovisionar y todos los servicios que deseas habilitar). En
esta guía, encontrarás una lista completa de todos los
recursos de Firebase que son compatibles con Terraform.
Abre el archivo main.tf.
En la configuración de provider, incluye la siguiente configuración de bloques
resource.
En este ejemplo básico, se crea un proyecto de Firebase nuevo y, luego, una
app para Android de Firebase dentro de ese proyecto.
# Terraform configuration to set up providers by version.
...
# Configures the provider to use the resource block's specified project for quota checks.
...
# Configures the provider to not use the resource block's specified project for quota checks.
...
# Creates a new Google Cloud project.
resource "google_project" "default" {
provider = google-beta.no_user_project_override
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for any service that requires the Blaze pricing plan
# (like Firebase Authentication with GCIP)
billing_account = "000000-000000-000000"
# Required for the project to display in any list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "default" {
provider = google-beta.no_user_project_override
project = google_project.default.project_id
for_each = toset([
"cloudbilling.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebase.googleapis.com",
# Enabling the ServiceUsage API allows the new project to be quota checked from now on.
"serviceusage.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "default" {
provider = google-beta
project = google_project.default.project_id
# Waits for the required APIs to be enabled.
depends_on = [
google_project_service.default
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "default" {
provider = google-beta
project = google_project.default.project_id
display_name = "My Awesome Android app"
package_name = "awesome.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.default,
]
}
Consulta una versión de este archivo de configuración de ejemplo con muchas anotaciones
Si no estás familiarizado con la infraestructura de proyectos y apps como
recursos, revisa la siguiente documentación:
# Terraform configuration to set up providers by version.
...
# Configures the provider to use the resource block's specified project for quota checks.
...
# Configures the provider to not use the resource block's specified project for quota checks.
...
# Creates a new Google Cloud project.
resource "google_project" "default" {
# Use the provider that enables the setup of quota checks for a new project
provider = google-beta.no_user_project_override
name = "Project Display Name" // learn more about the project name
project_id = "project-id-for-new-project" // learn more about the project ID
# Required for any service that requires the Blaze pricing plan
# (like Firebase Authentication with GCIP)
billing_account = "000000-000000-000000"
# Required for the project to display in any list of Firebase projects.
labels = {
"firebase" = "enabled" // learn more about the Firebase-enabled label
}
}
# Enables required APIs.
resource "google_project_service" "default" {
# Use the provider without quota checks for enabling APIS
provider = google-beta.no_user_project_override
project = google_project.default.project_id
for_each = toset([
"cloudbilling.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebase.googleapis.com",
# Enabling the ServiceUsage API allows the new project to be quota checked from now on.
"serviceusage.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
# This action essentially "creates a Firebase project" and allows the project to use
# Firebase services (like Firebase Authentication) and
# Firebase tooling (like the Firebase console).
# Learn more about the relationship between Firebase projects and Google Cloud.
resource "google_firebase_project" "default" {
# Use the provider that performs quota checks from now on
provider = google-beta
project = google_project.default.project_id
# Waits for the required APIs to be enabled.
depends_on = [
google_project_service.default
]
}
# Creates a Firebase Android App in the new project created above.
# Learn more about the relationship between Firebase Apps and Firebase projects.
resource "google_firebase_android_app" "default" {
provider = google-beta
project = google_project.default.project_id
display_name = "My Awesome Android app" # learn more about an app's display name
package_name = "awesome.package.name" # learn more about an app's package name
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.default,
]
}
Paso 2: Ejecuta los comandos de Terraform para crear la infraestructura especificada
Para aprovisionar los recursos y habilitar los servicios especificados en el archivo main.tf,
ejecuta los siguientes comandos desde el mismo directorio que contiene el archivo main.tf.
Para obtener información detallada sobre estos comandos, consulta la
documentación de Terraform.
Si es la primera vez que ejecutas comandos de Terraform en el
directorio, debes inicializar el directorio de configuración y, luego, instalar
el proveedor de Google Terraform. Para ello, ejecuta el siguiente comando:
terraform init
Ejecuta el siguiente comando para crear la infraestructura
especificada en el archivo main.tf:
terraform apply
Confirma que todo esté aprovisionado o habilitado como se esperaba:
Opción 1: Ejecuta el siguiente comando para ver
la configuración impresa en la terminal:
Los siguientes recursos de Firebase y Google son compatibles con Terraform. Además,
agregamos más recursos todo el tiempo. Por lo tanto, si no ves el recurso que quieres
administrar con Terraform, vuelve a consultar pronto para ver si está disponible o
solicítalo
presentando un problema en el repositorio de GitHub.
Administración de apps y proyectos de Firebase
google_firebase_project:
Habilita los servicios de Firebase en un proyecto existente de Google Cloud.
google_identity_platform_config:
Habilita Google Cloud Identity Platform (GCIP), que es el backend para Firebase Authentication,
y proporciona la configuración de autenticación a nivel de proyecto.
El proyecto en el que Terraform habilitará GCIP o Firebase Authentication
debe estar en el plan de precios Blaze (es decir, el proyecto debe tener asociada una
cuenta de Facturación de Cloud). Configura el atributo billing_account
en el recurso google_project
para hacerlo
de manera programática.
google_identity_platform_project_default_config:
Configura métodos de acceso locales, como el acceso anónimo, el acceso con correo electrónico y contraseña, y el acceso con autenticación por teléfono.
Implementar reglas de seguridad de Firebase Realtime Database mediante Terraform (obtén información para
implementar estas reglas
con otras herramientas, incluidas las opciones programáticas)
google_firestore_document:
Propaga una instancia de Cloud Firestore con un documento específico en una colección.
Importante: No uses datos reales de usuario final o de producción en este documento
de origen.
Cloud Storage para Firebase
google_firebase_storage_bucket:
Hace que un bucket de Cloud Storage existente sea accesible para los SDK de Firebase,
la autenticación y las reglas de seguridad de Firebase.
Importante: No uses datos reales de usuarios finales o de producción en este archivo.
Reglas de seguridad de Firebase (para Cloud Firestore y Cloud Storage)
Ten en cuenta que Firebase Realtime Database usa un sistema de aprovisionamiento diferente para sus
reglas de seguridad de Firebase.
google_firebaserules_ruleset:
Define las reglas de seguridad de Firebase que se aplican a la instancia de Cloud Firestore o a un
bucket de Cloud Storage.
google_firebaserules_release:
Implementa conjuntos de reglas específicos en la instancia de Cloud Firestore o en un
bucket de Cloud Storage.
Archivos de configuración de Terraform de muestra para casos de uso comunes
Configura Firebase Authentication con
GCIP
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se lo asocia con una cuenta de Facturación de Cloud (el plan de precios Blaze
es obligatorio en Firebase Authentication con GCIP),
se habilitan los servicios de Firebase para el proyecto, se configura Firebase Authentication con GCIP
y se registran tres tipos de apps diferentes con el proyecto.
Ten en cuenta que es necesario habilitar GCIP para configurar Firebase Authentication mediante Terraform.
# Creates a new Google Cloud project.
resource "google_project" "auth" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Associates the project with a Cloud Billing account
# (required for Firebase Authentication with GCIP).
billing_account = "000000-000000-000000"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "auth" {
provider = google-beta.no_user_project_override
project = google_project.auth.project_id
for_each = toset([
"cloudbilling.googleapis.com",
"cloudresourcemanager.googleapis.com",
"serviceusage.googleapis.com",
"identitytoolkit.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "auth" {
provider = google-beta
project = google_project.auth.project_id
depends_on = [
google_project_service.auth,
]
}
# Creates an Identity Platform config.
# Also enables Firebase Authentication with Identity Platform in the project if not.
resource "google_identity_platform_config" "auth" {
provider = google-beta
project = google_project.auth.project_id
# For example, you can configure to auto-delete Anonymous users.
autodelete_anonymous_users = true
# Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication.
depends_on = [
google_project_service.auth,
]
}
# Adds more configurations, like for the email/password sign-in provider.
resource "google_identity_platform_project_default_config" "auth" {
provider = google-beta
project = google_project.auth.project_id
sign_in {
allow_duplicate_emails = false
anonymous {
enabled = true
}
email {
enabled = true
password_required = false
}
}
# Wait for Authentication to be initialized before enabling email/password.
depends_on = [
google_identity_platform_config.auth
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
Aprovisiona la
instancia predeterminada de Firebase Realtime Database
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se habilitan los servicios de Firebase para el proyecto,
se aprovisiona la instancia predeterminada de Realtime Database del proyecto
y se registran tres tipos de apps diferentes con el proyecto.
# Creates a new Google Cloud project.
resource "google_project" "rtdb" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "rtdb" {
provider = google-beta.no_user_project_override
project = google_project.rtdb.project_id
for_each = toset([
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebasedatabase.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
}
# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database" {
provider = google-beta
project = google_project.rtdb.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations
region = "name-of-region"
# This value will become the first segment of the database's URL.
instance_id = "${google_project.rtdb.project_id}-default-rtdb"
type = "DEFAULT_DATABASE"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
Aprovisiona múltiples
instancias de Firebase Realtime Database
Este archivo de configuración crea un proyecto de Google Cloud nuevo,
lo asocia con una cuenta de Facturación de Cloud (se requiere el plan de precios Blaze
para varias instancias de Realtime Database), se habilitan los servicios de Firebase del proyecto, se aprovisionan varias instancias de Realtime Database
(incluida la instancia predeterminada de Realtime Database del proyecto)
y se registran tres tipos de apps diferentes con el proyecto.
# Creates a new Google Cloud project.
resource "google_project" "rtdb-multi" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Associate the project with a Cloud Billing account
# (required for multiple Realtime Database instances).
billing_account = "000000-000000-000000"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "rtdb-multi" {
provider = google-beta.no_user_project_override
project = google_project.rtdb-multi.project_id
for_each = toset([
"cloudbilling.googleapis.com",
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebasedatabase.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
}
# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database-default" {
provider = google-beta
project = google_project.rtdb-multi.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations
region = "name-of-region"
# This value will become the first segment of the database's URL.
instance_id = "${google_project.rtdb-multi.project_id}-default-rtdb"
type = "DEFAULT_DATABASE"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Provisions an additional Realtime Database instance.
resource "google_firebase_database_instance" "database-additional" {
provider = google-beta
project = google_project.rtdb-multi.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations
# This location doesn't need to be the same as the default database instance.
region = "name-of-region"
# This value will become the first segment of the database's URL.
instance_id = "name-of-additional-database-instance"
type = "USER_DATABASE"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
Aprovisiona la
instancia de Cloud Firestore
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se habilitan los servicios de Firebase para el proyecto,
se aprovisiona la instancia de Cloud Firestore del proyecto
y se registran tres tipos de apps diferentes con el proyecto.
También se aprovisionan reglas de seguridad de Firebase para la instancia de Cloud Firestore,
se crea un índice de Cloud Firestore
y se agrega un documento de Cloud Firestore con datos de origen.
# Creates a new Google Cloud project.
resource "google_project" "firestore" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "firestore" {
provider = google-beta.no_user_project_override
project = google_project.firestore.project_id
for_each = toset([
"cloudresourcemanager.googleapis.com",
"serviceusage.googleapis.com",
"firestore.googleapis.com",
"firebaserules.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
}
# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
name = "(default)"
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
location_id = "name-of-region"
# "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
type = "FIRESTORE_NATIVE"
concurrency_mode = "OPTIMISTIC"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a ruleset of Firestore Security Rules from a local file.
resource "google_firebaserules_ruleset" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
source {
files {
name = "firestore.rules"
# Write security rules in a local file named "firestore.rules".
# Learn more: https://firebase.google.com/docs/firestore/security/get-started
content = file("firestore.rules")
}
}
# Wait for Firestore to be provisioned before creating this ruleset.
depends_on = [
google_firestore_database.firestore,
]
}
# Releases the ruleset for the Firestore instance.
resource "google_firebaserules_release" "firestore" {
provider = google-beta
name = "cloud.firestore" # must be cloud.firestore
ruleset_name = google_firebaserules_ruleset.firestore.name
project = google_project.firestore.project_id
# Wait for Firestore to be provisioned before releasing the ruleset.
depends_on = [
google_firestore_database.firestore,
]
}
# Adds a new Firestore index.
resource "google_firestore_index" "indexes" {
provider = google-beta
project = google_project.firestore.project_id
collection = "quiz"
query_scope = "COLLECTION"
fields {
field_path = "question"
order = "ASCENDING"
}
fields {
field_path = "answer"
order = "ASCENDING"
}
# Wait for Firestore to be provisioned before adding this index.
depends_on = [
google_firestore_database.firestore,
]
}
# Adds a new Firestore document with seed data.
# Don't use real end-user or production data in this seed document.
resource "google_firestore_document" "doc" {
provider = google-beta
project = google_project.firestore.project_id
collection = "quiz"
document_id = "question-1"
fields = "{\"question\":{\"stringValue\":\"Favorite Database\"},\"answer\":{\"stringValue\":\"Firestore\"}}"
# Wait for Firestore to be provisioned before adding this document.
depends_on = [
google_firestore_database.firestore,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
Este es el conjunto de reglas de las reglas de seguridad de Cloud Firestore que deberían estar en un archivo local
llamado firestore.rules.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update: if request.auth != null;
}
}
Aprovisiona el
bucket predeterminado de Cloud Storage
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se habilitan los servicios de Firebase para el proyecto,
se aprovisiona el bucket de Cloud Storage predeterminado del proyecto
y se registran tres tipos de apps diferentes con el proyecto.
También aprovisionan reglas de seguridad de Firebase para el bucket de Cloud Storage
y se sube un archivo al bucket.
# Creates a new Google Cloud project.
resource "google_project" "storage" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "storage" {
provider = google-beta.no_user_project_override
project = google_project.storage.project_id
for_each = toset([
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebaserules.googleapis.com",
"firebasestorage.googleapis.com",
"storage.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "storage" {
provider = google-beta
project = google_project.storage.project_id
}
# Provisions the default Cloud Storage bucket for the project via Google App Engine.
resource "google_app_engine_application" "default" {
provider = google-beta
project = google_project.storage.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
# This will set the location for the default Storage bucket and the App Engine App.
location_id = "name-of-region-for-default-bucket"
# If you use Firestore, uncomment this to make sure Firestore is provisioned first.
# depends_on = [
# google_firestore_database.firestore
# ]
}
# Makes the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "default-bucket" {
provider = google-beta
project = google_project.storage.project_id
bucket_id = google_app_engine_application.default.default_bucket
}
# Creates a ruleset of Cloud Storage Security Rules from a local file.
resource "google_firebaserules_ruleset" "storage" {
provider = google-beta
project = google_project.storage.project_id
source {
files {
# Write security rules in a local file named "storage.rules".
# Learn more: https://firebase.google.com/docs/storage/security/get-started
name = "storage.rules"
content = file("storage.rules")
}
}
# Wait for the default Storage bucket to be provisioned before creating this ruleset.
depends_on = [
google_firebase_project.storage,
]
}
# Releases the ruleset to the default Storage bucket.
resource "google_firebaserules_release" "default-bucket" {
provider = google-beta
name = "firebase.storage/${google_app_engine_application.default.default_bucket}"
ruleset_name = "projects/${google_project.storage.project_id}/rulesets/${google_firebaserules_ruleset.storage.name}"
project = google_project.storage.project_id
}
# Uploads a new file to the default Storage bucket.
# Don't use real end-user or production data in this file.
resource "google_storage_bucket_object" "cat-picture" {
provider = google-beta
name = "cat.png"
source = "path/to/cat.png"
bucket = google_app_engine_application.default.default_bucket
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "storage" {
provider = google-beta
project = google_project.storage.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "storage" {
provider = google-beta
project = google_project.storage.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "storage" {
provider = google-beta
project = google_project.storage.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage,
]
}
Este es el conjunto de reglas de las reglas de seguridad de Cloud Storage que deberían estar en un archivo local
llamado storage.rules.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Aprovisiona
múltiples buckets de Cloud Storage
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se lo asocia con una cuenta de Facturación de Cloud (se requiere el plan de precios Blaze
en los casos con varios buckets),
se habilitan los servicios de Firebase para el proyecto,
se aprovisionan varios buckets de Cloud Storage (incluido el bucket predeterminado de Cloud Storage del proyecto)
y se registran tres tipos de apps diferentes con el proyecto.
También se aprovisionan reglas de seguridad de Firebase para el bucket de Cloud Storage
y se sube un archivo al bucket de Cloud Storage predeterminado.
# Creates a new Google Cloud project.
resource "google_project" "storage-multi" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Associates the project with a Cloud Billing account
# (required for multiple Cloud Storage buckets).
billing_account = "000000-000000-000000"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "storage-multi" {
provider = google-beta.no_user_project_override
project = google_project.storage-multi.project_id
for_each = toset([
"cloudbilling.googleapis.com",
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebaserules.googleapis.com",
"firebasestorage.googleapis.com",
"storage.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident.
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
}
# Provisions the default Cloud Storage bucket for the project via Google App Engine.
resource "google_app_engine_application" "default-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
# This will set the location for the default Storage bucket and the App Engine App.
location_id = "name-of-region-for-default-bucket"
# If you use Firestore, uncomment this to make sure Firestore is provisioned first.
# depends_on = [
# google_firestore_database.firestore
# ]
}
# Provisions an additional Cloud Storage bucket.
# Additional Cloud Storage buckets are not provisioned via App Engine.
resource "google_storage_bucket" "bucket-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
name = "name-of-additional-storage-bucket"
# See available locations: https://cloud.google.com/storage/docs/locations#available-locations
# This location does not need to be the same as the default Storage bucket.
location = "name-of-region-for-additional-bucket"
}
# Makes the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "default-bucket-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
bucket_id = google_app_engine_application.default-multi.default_bucket
}
# Makes the additional Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "bucket-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
bucket_id = google_storage_bucket.bucket-multi.name
}
# Creates a ruleset of Firebase Security Rules from a local file.
resource "google_firebaserules_ruleset" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
source {
files {
# Write security rules in a local file named "storage.rules"
# Learn more: https://firebase.google.com/docs/storage/security/get-started
name = "storage.rules"
content = file("storage.rules")
}
}
# Wait for the Storage buckets to be provisioned before creating this ruleset.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Releases the ruleset to the default Storage bucket.
resource "google_firebaserules_release" "default-bucket-multi" {
provider = google-beta
name = "firebase.storage/${google_app_engine_application.default-multi.default_bucket}"
ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"
project = google_project.storage-multi.project_id
}
# Releases the ruleset to the additional Storage bucket.
resource "google_firebaserules_release" "bucket-multi" {
provider = google-beta
name = "firebase.storage/${google_storage_bucket.bucket-multi.name}"
ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"
project = google_project.storage-multi.project_id
}
# Uploads a new file to the default Storage bucket.
# Do not use real end-user or production data in this file.
resource "google_storage_bucket_object" "cat-picture-multi" {
provider = google-beta
name = "cat.png"
source = "path/to/cat.png"
bucket = google_app_engine_application.default-multi.default_bucket
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
Este es el conjunto de reglas de las reglas de seguridad de Cloud Storage que deberían estar en un archivo local
llamado storage.rules.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Aprovisiona la
instancia de Cloud Firestore y el bucket predeterminado de Cloud Storage
Con esta configuración, se crea un proyecto de Google Cloud nuevo,
se habilitan los servicios de Firebase para el proyecto,
se aprovisiona la instancia de Cloud Firestore y, luego,
se aprovisiona el bucket predeterminado de Cloud Storage.
También aprovisiona reglas de seguridad de Firebase para la instancia de Cloud Firestore y el bucket
predeterminado de Cloud Storage.
# Creates a new Google Cloud project.
resource "google_project" "fs" { # fs = Firestore + Storage
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "fs" {
provider = google-beta.no_user_project_override
project = google_project.fs.project_id
for_each = toset([
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"firebaserules.googleapis.com",
"firebasestorage.googleapis.com",
"storage.googleapis.com",
"firestore.googleapis.com",
])
service = each.key
# Don't disable the service if the resource block is removed by accident
disable_on_destroy = false
}
# Enables Firebase services for the new project created above.
resource "google_firebase_project" "fs" {
provider = google-beta
project = google_project.fs.project_id
}
#### Set up Firestore before default Cloud Storage bucket ####
# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore-fs" {
provider = google-beta
project = google_project.fs.project_id
name = "(default)"
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
location_id = "name-of-region"
# "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
type = "FIRESTORE_NATIVE"
concurrency_mode = "OPTIMISTIC"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
depends_on = [
google_firebase_project.fs,
]
}
# Creates a ruleset of Firestore Security Rules from a local file.
resource "google_firebaserules_ruleset" "firestore-fs" {
provider = google-beta
project = google_project.fs.project_id
source {
files {
# Write security rules in a local file named "firestore.rules".
# Learn more: https://firebase.google.com/docs/firestore/security/get-started
name = "firestore.rules"
content = file("firestore.rules")
}
}
# Wait for Firestore to be provisioned before creating this ruleset.
depends_on = [
google_firestore_database.firestore-fs
]
}
# Releases the ruleset for the Firestore instance.
resource "google_firebaserules_release" "firestore-fs" {
provider = google-beta
name = "cloud.firestore" # must be cloud.firestore
ruleset_name = google_firebaserules_ruleset.firestore-fs.name
project = google_project.fs.project_id
# Wait for Firestore to be provisioned before releasing the ruleset.
depends_on = [
google_firestore_database.firestore-fs,
]
}
#### Set up default Cloud Storage default bucket after Firestore ####
# Provisions the default Cloud Storage bucket for the project via Google App Engine.
resource "google_app_engine_application" "default-bucket-fs" {
provider = google-beta
project = google_project.fs.project_id
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
# This will set the location for the default Storage bucket and the App Engine App.
location_id = "name-of-region" # Must be in the same location as Firestore (above)
# Wait for Firestore to be provisioned first.
# Otherwise, the Firestore instance will be provisioned in Datastore mode (unusable by Firebase).
depends_on = [
google_firestore_database.firestore-fs,
]
}
# Makes the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "default-bucket-fs" {
provider = google-beta
project = google_project.fs.project_id
bucket_id = google_app_engine_application.default-bucket-fs.default_bucket
}
# Creates a ruleset of Cloud Storage Security Rules from a local file.
resource "google_firebaserules_ruleset" "default-bucket-fs" {
provider = google-beta
project = google_project.fs.project_id
source {
files {
# Write security rules in a local file named "storage.rules".
# Learn more: https://firebase.google.com/docs/storage/security/get-started
name = "storage.rules"
content = file("storage.rules")
}
}
# Wait for the Cloud Storage bucket to be provisioned before creating this ruleset.
depends_on = [
google_firebase_project.fs,
]
}
# Releases the ruleset to the default Storage bucket.
resource "google_firebaserules_release" "default-bucket-fs" {
provider = google-beta
name = "firebase.storage/${google_app_engine_application.default-bucket-fs.default_bucket}"
ruleset_name = "projects/${google_project.fs.project_id}/rulesets/${google_firebaserules_ruleset.default-bucket-fs.name}"
project = google_project.fs.project_id
}
Este es el conjunto de reglas de las reglas de seguridad de Cloud Firestore que deberían estar en un archivo local
llamado firestore.rules.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update: if request.auth != null;
}
}
Este es el conjunto de reglas de las reglas de seguridad de Cloud Storage que deberían estar en un archivo local
llamado storage.rules.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Solución de problemas y preguntas frecuentes
Deseas obtener
más información sobre todos los diferentes atributos relacionados con el proyecto (como
project y user_project_override)
En esta guía, se usan los siguientes atributos de Terraform cuando se trabaja con “proyectos”.
project dentro de un bloque resource
Recomendado: Siempre que sea posible, incluye el atributo project en cada
bloque resource.
Cuando incluyes un atributo de proyecto, Terraform creará la infraestructura
especificada en el bloque de recursos del proyecto indicado. En esta guía y
en nuestros archivos de configuración de muestra, se usa esta práctica.
Consulta la documentación oficial de Terraform sobre
project.
user_project_override dentro del bloque provider
Para aprovisionar la mayoría de los recursos, debes usar
user_project_override = true, lo que significa que debes verificar la cuota en tu
propio proyecto de Firebase. Sin embargo, si quieres que tu proyecto acepte
verificaciones de cuotas, debes debes usar user_project_override = false.
Recibirás este error:
generic::permission_denied: Firebase Tos Not Accepted.
Asegúrate de que en la cuenta de usuario que usas para ejecutar comandos de gcloud CLI
se acepten las Condiciones del Servicio de Firebase.
Para verificarlo, usa un navegador en el que hayas accedido a la cuenta del usuario y
revisa si puedes ver un proyecto de Firebase en
Firebase console. Si es así,
la cuenta de usuario aceptó las
Condiciones del Servicio de Firebase.
Si no puedes ver ningún proyecto de Firebase, es probable que la cuenta de usuario
no haya aceptado las Condiciones del Servicio de Firebase. Para solucionar este problema, crea un proyecto de Firebase
nuevo a través de Firebase console y acepta las
Condiciones del Servicio de Firebase como parte de su creación. Puedes borrar este proyecto de inmediato en la
Configuración del proyecto de la consola.
Después de ejecutar
terraform apply, verás este error:
generic::permission_denied: IAM authority does not have the
permission.
Espera unos minutos y vuelve a intentar ejecutar terraform apply.
No
se pudo crear un recurso, pero cuando vuelves a ejecutar terraform apply
, dice ALREADY_EXISTS.
Esto podría deberse a una demora en la propagación en varios sistemas. Para resolver este
problema, importa el recurso al estado de Terraform mediante la ejecución del siguiente comando:
terraform import. Luego, vuelve a ejecutar terraform apply.
Cuando trabajas con
Cloud Firestore, recibes este error: Error creating Index: googleapi:
Error 409;...Concurrent access -- try again
Como sugiere el error, Terraform puede intentar aprovisionar varios índices
o crear un documento al mismo tiempo, y encontrar un error de simultaneidad.
Vuelve a ejecutar terraform apply.
Recibirás
este error:
"you may need to specify 'X-Goog-User-Project' HTTP header for quota and
billing purposes".
Este error significa que Terraform no sabe en qué proyecto
verificar la cuota. Para solucionar el problema, verifica lo siguiente en el bloque resource:
Asegúrate especificar un valor para el atributo project.
Asegúrate de usar el proveedor con user_project_override = true
(sin alias), que aparece como google-beta en las muestras de Firebase.
Cuando creas un
proyecto nuevo de Google Cloud, aparece el error de que el ID del proyecto especificado para
el proyecto nuevo ya existe.
Estos son algunos de los motivos por los que es posible que ya exista el ID del proyecto:
El proyecto asociado con ese ID le pertenece a otra persona.
Solución: Elige otro ID del proyecto.
El proyecto asociado con ese ID se borró recientemente (en estado de eliminación
no definitiva).
Solución: Si crees que el proyecto asociado con el ID te
pertenece,
verifica su estado mediante el comando projects.get de la API de REST.
El proyecto asociado con ese ID existe correctamente en el usuario actual. Una
posible causa del error podría ser que se interrumpió
un terraform apply anterior.
Solución: Ejecuta los siguientes comandos: terraform import google_project.default PROJECT_ID
y, luego, terraform import google_firebase_project.default PROJECT_ID
Cuando
intentas aprovisionar Cloud Firestore y, luego, Cloud Storage (a través de
google_app_engine_application), aparece este error:
Error: Error creating App Engine application: googleapi: Error 409:
Cannot create Firestore database resource <resource-name> since it
already exists at location <location-id>, alreadyExists.
Una aplicación de App Engine requiere una instancia de Cloud Firestore, pero solo
puedes tener una de ellas por proyecto. Por lo tanto, como se sugiere en el mensaje de error,
si ya aprovisionaste la instancia de Cloud Firestore del proyecto en una
ubicación, App Engine mostrará un error si intentas aprovisionar una instancia de Cloud Firestore
en una ubicación diferente. App Engine cree que estás intentando
“aprovisionar de nuevo” la instancia de Cloud Firestore existente.
A fin de resolver este error, usa la misma ubicación para Cloud Firestore y la
aplicación de App Engine. Si necesitas un bucket de Cloud Storage en una
ubicación diferente de Cloud Firestore, puedes aprovisionar buckets adicionales
(consulta la
configuración de muestra para crear varios buckets de
Cloud Storage).
Cuando
intentes aprovisionar Cloud Storage (a través de
google_app_engine_application) y, luego, Cloud Firestore, verás
este error:
Error: Error creating Database: googleapi: Error 409: Database already
exists. Please use another database_id.
Cuando aprovisionas un bucket predeterminado de Cloud Storage de un proyecto (mediante
google_app_engine_application) y el proyecto aún no tiene una
instancia de Cloud Firestore, google_app_engine_application aprovisiona
automáticamente la instancia de Cloud Firestore del proyecto.
Por lo tanto, si la instancia de Cloud Firestore de tu proyecto ya se aprovisionó,
google_firestore_database fallará si intentas aprovisionar de manera explícita una
instancia de Cloud Firestore.
Una vez que se aprovisiona la instancia de Cloud Firestore del proyecto, no puedes
“aprovisionarla de nuevo” ni cambiar su ubicación. Para evitar que se produzca el error,
quita el bloque de recursos google_firestore_database del archivo de configuración.
Sin embargo, ten en cuenta que recomendamos aprovisionar Cloud Firestore antes que el
bucket predeterminado de Cloud Storage del proyecto (consulta el motivo a continuación).