بدء استخدام Terraform وFirebase

بدأت Firebase في توفير دعم Terraform. إذا كنت أحد أعضاء فريق يريد إنشاء مشاريع Firebase بشكل آلي وموحد باستخدام موارد محدّدة تم توفيرها وخدمات مفعّلة، قد يكون استخدام Terraform مع Firebase مناسبًا لك.

يتضمن سير العمل الأساسي لاستخدام Terraform مع Firebase ما يلي:

  • إنشاء ملف إعدادات Terraform (ملف .tf) وتخصيصه لتحديد البنية الأساسية التي تريد توفيرها (أي الموارد التي تريد توفيرها والخدمات التي تريد تفعيلها)

  • استخدام أوامر gcloud CLI التي تتفاعل مع Terraform ل توفير البنية الأساسية المحدّدة في ملف .tf

ما هي الإجراءات التي يمكنك اتّخاذها باستخدام Terraform وFirebase؟

مثال على سير العمل العام في هذا الدليل هو إنشاء مشروع جديد على Firebase باستخدام تطبيق Android. ولكن يمكنك تنفيذ إجراءات أكثر باستخدام Terraform، مثل:

  • حذف البنية الأساسية الحالية وتعديلها باستخدام Terraform

  • إدارة الإعدادات والمهام الخاصة بالمنتج باستخدام Terraform، مثل:

    • تفعيل مقدّمي خدمة تسجيل الدخول إلى Firebase Authentication
    • إنشاء حِزم Cloud Storage أو نُسخ قاعدة بيانات ونشر Firebase Security Rules لها

يمكنك استخدام ملفات الإعدادات وأوامر Terraform العادية لتنفيذ كل هذه المهام. لمساعدتك في ذلك، قدّمنا عيّنات من ملفات إعدادات Terraform لعدة حالات استخدام شائعة.



سير العمل العام لاستخدام Terraform مع Firebase

المتطلبات الأساسية

هذا الدليل هو مقدّمة لاستخدام Terraform مع Firebase، لذا يفترض أنّك تمتلك معرفة dasar بـ Terraform. تأكَّد من إكمال المتطلبات الأساسية التالية قبل بدء سير العمل هذا.

  • ثبِّت Terraform وتعرَّف على Terraform باستخدام الأدلة الرسمية.

  • ثبِّت Google Cloud CLI (gcloud CLI). سجِّل الدخول باستخدام حساب مستخدم أو حساب خدمة.

    • في حال استخدام حساب مستخدم، يجب أن تكون قد وافقت على بنود خدمة Firebase. يعني قبولك لبنود خدمة Firebase أنّه يمكنك عرض مشروع Firebase في وحدة تحكُّم Firebase.
    • لكي يتّخذ Terraform إجراءات معيّنة (مثل إنشاء المشاريع)، يجب أن يكون الإجراء التالي صحيحًا:
      • يجب أن يكون لدى حساب المستخدم أو حساب الخدمة إذن الوصول الساري في سياسة "إدارة الهوية وإمكانية الوصول" (IAM) للقيام بهذه الإجراءات.
      • إذا كان حساب المستخدم أو حساب الخدمة جزءًا من مؤسسة Google Cloud، يجب أن تسمح سياسات المؤسسة للحساب باتخاذ هذه الإجراءات.


الخطوة 1: إنشاء ملف إعدادات Terraform وتخصيصه

يحتاج ملف إعدادات Terraform إلى قسمَين رئيسيَين (يتم وصفهما بالتفصيل أدناه):

إعداد provider

يجب إعداد provider بغض النظر عن منتجات Firebase أو خدماتها المعنيّة.

  1. أنشئ ملف إعدادات Terraform (مثل ملف main.tf) في ملف الدليل المحلي.

    في هذا الدليل، ستستخدم ملف الإعداد هذا لتحديد كل من provider الإعداد وجميع البنية الأساسية التي تريد أن تنشئها Terraform. يُرجى العلم، مع ذلك، أنّ لديك خيارات حول كيفية تضمين إعداد مقدّم الخدمة.

    تتوفّر لك الخيارات التالية لكيفية تضمين عملية إعداد provider في باقي إعدادات Terraform:

    • الخيار 1: تضمينه في أعلى ملف .tf config واحد من Terraform (كما هو موضّح في هذا الدليل).

      • استخدِم هذا الخيار إذا كنت قد بدأت للتو استخدام Terraform أو كنت بصدد تجربته مع Firebase.
    • الخيار 2: تضمينها في ملف .tf منفصل (مثل ملف provider.tf )، بخلاف ملف .tf الذي تحدّد فيه البنية الأساسية التي تريد إنشاؤها (مثل ملف main.tf).

      • استخدِم هذا الخيار إذا كنت جزءًا من فريق أكبر يحتاج إلى توحيد عملية الإعداد.
      • عند تنفيذ أوامر Terraform، يجب أن يكون كل من ملف provider.tf وملف main.tf في الدليل نفسه.

  2. أدرِج إعداد provider التالي في أعلى ملف main.tf.

    يجب استخدام مقدّم خدمة google-beta لأنّ هذا الإصدار هو إصدار تجريبي من استخدام Firebase مع Terraform. يُرجى توخّي الحذر عند استخدام هذه الميزة في قناة الإصدار العلني.

    # Terraform configuration to set up providers by version.
    terraform {
      required_providers {
        google-beta = {
          source  = "hashicorp/google-beta"
          version = "~> 5.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
    }

    اطّلِع على مزيد من المعلومات عن الأنواع المختلفة من السمات ذات الصلة بالمشروع (بما في ذلك ما يُطلق عليه هذا الدليل "مشروع التحقّق من الحصة") عند استخدام Terraform مع Firebase.

  3. انتقِل إلى القسم التالي لإكمال ملف الإعداد وتحديد البنية الأساسية التي تريد إنشاؤها.

تحديد البنية الأساسية التي تريد إنشاؤها باستخدام وحدات resource

في ملف إعدادات Terraform (ملف main.tf في هذا الدليل)، عليك تحديد كل البنية الأساسية التي تريد أن تنشئها Terraform (أي كل الموارد التي تريد توفيرها وجميع الخدمات التي تريد تفعيلها). في هذا الدليل، يمكنك العثور على قائمة كاملة بكل موارد Firebase المتوافقة مع Terraform.

  1. افتح ملف main.tf.

  2. ضمن إعداد provider، أدرِج الإعداد التالي لresource الوحدات.

    ينشئ هذا المثال الأساسي مشروعًا جديدًا على Firebase، ثمّ ينشئ تطبيق Android على Firebase ضمن هذا المشروع.

    # 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,
      ]
    }

إذا لم تكن على دراية بالبنية الأساسية للمشاريع والتطبيقات كموارد، راجِع المستندات التالية:

# 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,
  ]
}


الخطوة 2: تنفيذ أوامر Terraform لإنشاء البنية الأساسية المحدّدة

لتوفير الموارد وتفعيل الخدمات المحدّدة في ملف main.tf ، نفِّذ الأوامر التالية من الدليل نفسه الذي يتضمّن ملف main.tf. للحصول على معلومات تفصيلية عن هذه الأوامر، يُرجى الاطّلاع على مستندات Terraform.

  1. إذا كانت هذه هي المرة الأولى التي تُنفِّذ فيها أوامر Terraform في directory، عليك بدء ملف الإعدادات وتثبيت Google Terraform provider. يمكنك إجراء ذلك من خلال تنفيذ الأمر التالي:

    terraform init
  2. أنشئ البنية الأساسية المحدّدة في ملف main.tf من خلال تنفيذ الأمر التالي:

    terraform apply
  3. تأكَّد من أنّه تم توفير كل العناصر أو تفعيلها على النحو المتوقّع:

    • الخيار 1: الاطّلاع على الإعدادات المطبوعة في وحدة التحكّم عن بُعد من خلال تنفيذ الأمر التالي:

      terraform show
    • الخيار 2: يمكنك عرض مشروعك على Firebase في Firebase وحدة التحكّم.



موارد Firebase المتوافقة مع Terraform

تتوفّر أدوات Terraform في المراجع التالية حول Firebase وGoogle. ونحن نعمل على إضافة المزيد من المراجع باستمرار. إذا لم يظهر لك المورد الذي تريد تدبيره باستخدام Terraform، يُرجى التحقّق مرة أخرى قريبًا لمعرفة ما إذا كان متاحًا أو طلبه من خلال تسجيل مشكلة في مستودع GitHub.


إدارة مشاريع وتطبيقات Firebase

  • google_firebase_project: تفعيل خدمات Firebase في مشروع Google Cloud حالي

  • تطبيقات Firebase


Firebase Authentication

  • google_identity_platform_config: تفعيل Google Cloud Identity Platform (GCIP) (وهو الخلفية لخدمة Firebase Authentication) وتوفير إعدادات المصادقة على مستوى المشروع

    • يتطلب ضبط Firebase Authentication من خلال Terraform تفعيل GCIP. احرص على مراجعة نموذج ملف .tf لمعرفة كيفية إعداد Firebase Authentication.

    • يجب أن يكون المشروع الذي ستفعّل فيه Terraform "شركاء تكنولوجيا المعلومات في Google" و/أو Firebase Authentication مضمّنًا في خطة أسعار Blaze (أي أن يكون للمشروع حساب Cloud Billing مرتبطًا به). يمكنك إجراء ذلك آليًا من خلال ضبط سمة billing_account في مورد google_project.

    • يتيح هذا المرجع أيضًا المزيد من الإعدادات، مثل طرق تسجيل الدخول على الجهاز، مثل المصادقة المجهولة الهوية وعبر البريد الإلكتروني/كلمة المرور والهاتف، بالإضافة إلى حظر الدوال والنطاقات المعتمَدة.

  • google_identity_platform_default_supported_idp_config: ضبط موفِّري الهوية الموحّدين الشائعين، مثل Google أو Facebook أو Apple

  • identity_platform_oauth_idp_config: ضبط مصادر موفِّر الهوية (IdP) في OAuth بشكل عشوائي

  • google_identity_platform_inbound_saml_config — ضبط عمليات دمج SAML

الميزة غير متاحة بعد:

  • ضبط المصادقة المتعدّدة العوامل (MFA) من خلال Terraform

Firebase Data Connect


Firebase Realtime Database

الميزة غير متاحة بعد:

  • نشر Firebase Realtime Database Security Rules عبر Terraform (تعرَّف على كيفية نشر هذه Rules باستخدام أدوات أخرى، بما في ذلك الخيارات الآلية)

Cloud Firestore

  • google_firestore_database: إنشاء مثيل Cloud Firestore

  • google_firestore_index: تفعيل طلبات بحث فعّالة لـ Cloud Firestore

  • google_firestore_document: إنشاء مثيل Cloud Firestore باستخدام مستند معيّن في مجموعة

    ملاحظة مهمة: لا تستخدِم بيانات حقيقية للمستخدمين النهائيين أو بيانات الإنتاج في مستند التمهيد هذا.


Cloud Storage for Firebase

  • google_firebase_storage_bucket: إتاحة الوصول إلى حزمة Cloud Storage حالية لحِزم تطوير البرامج (SDK) لمنصّة Firebase، والمصادقة، وFirebase Security Rules

  • google_storage_bucket_object — إضافة عنصر إلى حزمة Cloud Storage

    ملاحظة مهمة: لا تستخدِم بيانات حقيقية للمستخدم النهائي أو بيانات الإنتاج في هذا الملف.


Firebase Security Rules (لكل من Cloud Firestore وCloud Storage)

يُرجى العِلم أنّ Firebase Realtime Database تستخدم نظامًا مختلفًا لتوفير Firebase Security Rules.

  • google_firebaserules_ruleset: تحديد Firebase Security Rules التي تنطبق على مثيل Cloud Firestore أو مجرّد Cloud Storage

  • google_firebaserules_release: نشر مجموعات قواعد معيّنة على مثيل Cloud Firestore أو في حزمة Cloud Storage


Firebase App Check


Firebase Extensions



نماذج ملفات ضبط Terraform لحالات الاستخدام الشائعة

يؤدي هذا الإعداد إلى إنشاء مشروع جديد على Google Cloud، وربط المشروع بحساب Cloud Billing (خطة أسعار Blaze مطلوبة لاستخدام Firebase Authentication مع GCIP)، وتفعيل خدمات Firebase للمشروع، وإعداد Firebase Authentication باستخدام GCIP، وتسجيل ثلاثة أنواع مختلفة من التطبيقات مع المشروع.

يُرجى العِلم أنّ تفعيل GCIP مطلوب لإعداد Firebase Authentication عبر 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

  # Auto-deletes anonymous users
  autodelete_anonymous_users = true

  # Configures local sign-in methods, like anonymous, email/password, and phone authentication.
  sign_in {
    allow_duplicate_emails = true

    anonymous {
      enabled = true
    }

    email {
      enabled = true
      password_required = false
    }

    phone_number {
      enabled = true
      test_phone_numbers = {
        "+11231231234" = "000000"
      }
    }
  }

  # Sets an SMS region policy.
  sms_region_config {
    allowlist_only {
      allowed_regions = [
        "US",
        "CA",
      ]
    }
  }

  # Configures blocking functions.
  blocking_functions {
    triggers {
      event_type = "beforeSignIn"
      function_uri = "https://us-east1-${google_project.auth.project_id}.cloudfunctions.net/before-sign-in"
    }
    forward_inbound_credentials {
      refresh_token = true
      access_token = true
      id_token = true
    }
  }

  # Configures a temporary quota for new signups for anonymous, email/password, and phone number.
  quota {
    sign_up_quota_config {
      quota = 1000
      start_time = ""
      quota_duration = "7200s"
    }
  }

  # Configures authorized domains.
  authorized_domains = [
    "localhost",
    "${google_project.auth.project_id}.firebaseapp.com",
    "${google_project.auth.project_id}.web.app",
  ]

  # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication.
  depends_on = [
    google_project_service.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,
  ]
}

يؤدي هذا الإعداد إلى إنشاء مشروع Google Cloud جديد، وتفعيل خدمات Firebase للمشروع، وتوفير خدمة Data Connect.

# Creates a new Google Cloud project.
resource "google_project" "dataconnect" {
  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 to use Firebase Data Connect).
  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" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.dataconnect.project_id
  for_each = toset([
    "serviceusage.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebasedataconnect.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 earlier.
resource "google_firebase_project" "dataconnect" {
  provider = google-beta
  project  = google_project.dataconnect.project_id

  depends_on = [google_project_service.services]
}

# Create a Firebase Data Connect service
resource "google_firebase_data_connect_service" "dataconnect-default" {
  project         = google_firebase_project.dataconnect.project
  location        = "name-of-region-for-service"
  service_id      = "${google_firebase_project.dataconnect.project}-default-fdc"
  deletion_policy = "DEFAULT"
}

يؤدي هذا الإعداد إلى إنشاء مشروع Google Cloud جديد، وتفعيل خدمات Firebase للمشروع، وتوفير مثيل Realtime Database التلقائي للمشروع، وتسجيل ثلاثة أنواع مختلفة من التطبيقات في المشروع.

# 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/database/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,
  ]
}

تؤدي عملية الإعداد هذه إلى إنشاء مشروع جديد على Google Cloud، وربط المشروع بحساب Cloud Billing (تُشترَط خطة أسعار Blaze لإنشاء عدة نُسخ من Realtime Database)، وتفعيل خدمات Firebase للمشروع، وتوفير عدة نُسخ من Realtime Database (بما في ذلك النسخة التلقائية من Realtime Database للمشروع)، وتسجيل ثلاثة أنواع مختلفة من التطبيقات مع المشروع.

# 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/database/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,
  ]
}

يؤدي هذا الإعداد إلى إنشاء مشروع Google Cloud جديد، وتفعيل خدمات Firebase للمشروع، وتوفير مثيل Cloud Firestore التلقائي للمشروع، وتسجيل ثلاثة أنواع مختلفة من التطبيقات في المشروع.

ويوفّر أيضًا Firebase Security Rules لمثيل Cloud Firestore التلقائي، وينشئ فهرسًا Cloud Firestore، ويضيف مستند Cloud Firestore يتضمّن بيانات أساسية.

# 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/firestore/locations
  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,
  ]
}

هذه هي مجموعة قواعد Cloud Firestore Security Rules التي يجب أن تكون في ملف محلي يحمل اسم firestore.rules.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, create, update: if request.auth != null;
    }
  }
}

تؤدي عملية الضبط هذه إلى إنشاء مشروع Google Cloud جديد، وربط المشروع بحساب Cloud Billing (خطة أسعار Blaze مطلوبة للمجموعات الإضافية)، وتفعيل خدمات Firebase للمشروع، وتوفير مجموعات Cloud Storage إضافية غير تلقائية، وتسجيل ثلاثة أنواع مختلفة من التطبيقات مع المشروع.

ويوفّر أيضًا Firebase Security Rules لكل مجموعة بيانات Cloud Storage، ويحمِّل ملفًا إلى إحدى مجموعات البيانات Cloud Storage.

# 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 a Cloud Storage bucket.
resource "google_storage_bucket" "bucket-1" {
  provider = google-beta
  project  = google_project.storage-multi.project_id
  name     = "name-of-storage-bucket"
  # See available locations: https://cloud.google.com/storage/docs/locations#available-locations
  location = "name-of-region-for-bucket"
}

# Provisions an additional Cloud Storage bucket.
resource "google_storage_bucket" "bucket-2" {
  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 existing Storage bucket.
  location = "name-of-region-for-additional-bucket"
}

# Makes the first Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "bucket-1" {
  provider  = google-beta
  project   = google_project.storage-multi.project_id
  bucket_id = google_storage_bucket.bucket-1.name
}

# Makes the additional Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "bucket-2" {
  provider  = google-beta
  project   = google_project.storage-multi.project_id
  bucket_id = google_storage_bucket.bucket-2.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 first Storage bucket.
resource "google_firebaserules_release" "bucket-1" {
  provider     = google-beta
  name         = "firebase.storage/${google_storage_bucket.bucket-1.name}"
  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-2" {
  provider     = google-beta
  name         = "firebase.storage/${google_storage_bucket.bucket-2.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 first 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_storage_bucket.bucket-1.name
}

# 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"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.storage-multi,
  ]
}

هذه هي مجموعة قواعد Cloud Storage Security Rules التي يجب أن تكون في ملف محلي يحمل اسم storage.rules.

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /some_folder/{fileName} {
      allow read, write: if request.auth != null;
    }
  }
}

يؤدي هذا الإعداد إلى إنشاء مشروع Google Cloud جديد، وتفعيل خدمات Firebase للمشروع، وإعداد Firebase App Check وتفعيل فرضه على Cloud Firestore كي لا يمكن الوصول إليه إلا من تطبيق Android.

# Creates a new Google Cloud project.
resource "google_project" "appcheck" {
  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" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.appcheck.project_id
  for_each = toset([
    "cloudresourcemanager.googleapis.com",
    "firebase.googleapis.com",
    "firebaseappcheck.googleapis.com",
    "firestore.googleapis.com",
    "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 earlier.
resource "google_firebase_project" "appcheck" {
  provider = google-beta
  project  = google_project.appcheck.project_id

  depends_on = [google_project_service.services]
}

# Provisions the Firestore database instance.
resource "google_firestore_database" "database" {
  provider = google-beta
  project  = google_firebase_project.appcheck.project
  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.appcheck,
  ]
}

# Creates a Firebase Android App in the new project created earlier.
resource "google_firebase_android_app" "appcheck" {
  provider     = google-beta
  project      = google_firebase_project.appcheck.project
  display_name = "Play Integrity app"
  package_name = "package.name.playintegrity"
  sha256_hashes = [
    # TODO: insert your Android app's SHA256 certificate
  ]
}

# It takes a while for App Check to recognize the new app
# If your app already exists, you don't have to wait 30 seconds.
resource "time_sleep" "wait_30s" {
  depends_on      = [google_firebase_android_app.appcheck]
  create_duration = "30s"
}

# Register the Android app with the Play Integrity provider
resource "google_firebase_app_check_play_integrity_config" "appcheck" {
  provider = google-beta
  project  = google_firebase_project.appcheck.project
  app_id   = google_firebase_android_app.appcheck.app_id

  depends_on = [time_sleep.wait_30s, google_firestore_database.database]

  lifecycle {
    precondition {
      condition     = length(google_firebase_android_app.appcheck.sha256_hashes) > 0
      error_message = "Provide a SHA-256 certificate on the Android App to use App Check"
    }
  }
}

# Enable enforcement of App Check for Firestore
resource "google_firebase_app_check_service_config" "firestore" {
  provider = google-beta

  project    = google_firebase_project.appcheck.project
  service_id = "firestore.googleapis.com"

  depends_on = [google_project_service.services]
}

يؤدي هذا الإعداد إلى إنشاء مشروع Google Cloud جديد، وتفعيل خدمات Firebase للمشروع، وتثبيت مثيل جديد من Firebase Extension في المشروع. إذا كانت النسخة متوفّرة، تتم تعديل مَعلماتها استنادًا إلى القيم المقدَّمة في الإعداد.

# Creates a new Google Cloud project.
resource "google_project" "extensions" {
  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 to use Firebase Extensions).
  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" "extensions" {
  provider = google-beta.no_user_project_override
  project  = google_project.extensions.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "serviceusage.googleapis.com",
    "firebase.googleapis.com",
    "firebaseextensions.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" "extensions" {
  provider = google-beta
  project  = google_project.extensions.project_id

  depends_on = [
    google_project_service.extensions,
  ]
}

# Installs an instance of the "Translate Text in Firestore" extension.
# Or updates the extension if the specified instance already exists.
resource "google_firebase_extensions_instance" "translation" {
  provider = google-beta
  project = google_project.extensions.project_id

  instance_id = "translate-text-in-firestore"
  config {
    extension_ref = "firebase/firestore-translate-text"

    params = {
      COLLECTION_PATH      = "posts/comments/translations"
      DO_BACKFILL          = true
      LANGUAGES            = "ar,en,es,de,fr"
      INPUT_FIELD_NAME     = "input"
      LANGUAGES_FIELD_NAME = "languages"
      OUTPUT_FIELD_NAME    = "translated"
    }

    system_params = {
      "firebaseextensions.v1beta.function/location"                   = "us-central1"
      "firebaseextensions.v1beta.function/memory"                     = "256"
      "firebaseextensions.v1beta.function/minInstances"               = "0"
      "firebaseextensions.v1beta.function/vpcConnectorEgressSettings" = "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED"
    }
  }
}



تحديد المشاكل وحلّها والأسئلة الشائعة

يستخدم هذا الدليل سمات Terraform التالية عند العمل مع "المشاريع".

project ضمن قطعة أرض مساحتها resource

يُنصح بتضمين سمة project في كلّ كتلة resource كلّما أمكن.

من خلال تضمين سمة مشروع، ستنشئ Terraform البنية الأساسية المحدّدة في وحدة الموارد ضمن المشروع المحدّد. يستخدم هذا الدليل وملفات الإعدادات النموذجية هذه الممارسة.

اطّلِع على المستندات الرسمية لـ Terraform حول project.

user_project_override ضمن مجموعة provider

لتوفير معظم الموارد، عليك استخدام user_project_override = true، ما يعني التحقّق من الحصة مقارنةً بمشروعك على Firebase. ومع ذلك، لإعداد مشروعك الجديد كي يقبل عمليات التحقّق من الحصة، عليك أولاً استخدام user_project_override = false.

اطّلِع على المستندات الرسمية لـ Terraform حول user_project_override.

تأكَّد من أنّ حساب المستخدم الذي تستخدمه لتشغيل gcloud CLI الطلبات قد وافق على بنود خدمة Firebase.

  • يمكنك إجراء هذا التحقّق باستخدام متصفّح تم تسجيل الدخول إلى حساب المستخدم من خلاله ومحاولة عرض مشروع حالي على Firebase في وحدة تحكّم Firebase. إذا كان بإمكانك عرض مشروع حالي على Firebase، يعني ذلك أنّ حساب المستخدم قد قبل بنود خدمة Firebase.

  • إذا لم تتمكّن من عرض أي مشروع حالي على Firebase، من المحتمل أنّ حساب المستخدم لم يقبل بنود خدمة Firebase. لحلّ هذه المشكلة، أنشِئ مشروعًا جديدًا على Firebase من خلال وحدة تحكّم Firebase واقبل بنود خدمة Firebase كجزء من إنشاء المشروع. يمكنك حذف هذا المشروع على الفور من خلال إعدادات المشروع في وحدة التحكّم.

يُرجى الانتظار بضع دقائق، ثم إعادة تشغيل terraform apply.

قد يرجع ذلك إلى تأخّر النشر في الأنظمة المختلفة. يمكنك محاولة حلّ هذه المشكلة من خلال استيراد المورد إلى حالة Terraform من خلال تشغيل terraform import. بعد ذلك، حاوِل تشغيل terraform apply مرة أخرى.

يمكنك الاطّلاع على كيفية استيراد كل مورد في قسم "الاستيراد" من مستندات Terraform (على سبيل المثال، مستندات"الاستيراد" الخاصة بـ Cloud Firestore).

كما يشير الخطأ، قد يحاول Terraform توفير فهارس متعددة و/أو إنشاء مستند في الوقت نفسه وواجه خطأ في التزامن. يُرجى محاولة تشغيل terraform apply مرة أخرى.

يعني هذا الخطأ أنّ Terraform لا يعرف المشروع الذي يجب التحقّق من الحصة في إطاره. لتحديد المشاكل وحلّها، يُرجى التحقّق مما يلي في قالب resource:

  • تأكَّد من تحديد قيمة لسمة project.
  • تأكَّد من استخدام مقدّم الخدمة مع user_project_override = true (بدون عنوان بديل)، والذي يكون google-beta في نماذج Firebase.

في ما يلي الأسباب المحتمَلة لوجود معرّف المشروع حاليًا:

  • المشروع المرتبط بهذا المعرّف مملوك لشخص آخر.

    • لحلّ المشكلة: اختَر رقم تعريف مشروع آخر.
  • تم حذف المشروع المرتبط بهذا المعرّف مؤخرًا (في حالة حذف مؤقت).

    • لحلّ المشكلة: إذا كنت تعتقد أنّ المشروع المرتبط برقم التعريف ينتمي إليك، تحقّق من حالة المشروع باستخدام projects.get REST API.
  • يتوفّر المشروع المرتبط بهذا المعرّف بشكل صحيح ضمن المستخدم الحالي. أحد الأسباب المحتملة لهذا الخطأ هو أنّه تم توقّف الإجراء terraform apply السابق.

    • لحلّ هذه المشكلة: نفِّذ الأوامر التالية:
      terraform import google_project.default PROJECT_ID ثم
      terraform import google_firebase_project.default PROJECT_ID

إذا أعددت حزمة Cloud Storage التلقائية (من خلال google_app_engine_application) قبل محاولة إعداد مثيل Cloud Firestore التلقائي، ستلاحظ أنّه سبق أن تم إعداد مثيل Cloud Firestore التلقائي. يُرجى العِلم أنّ مثيل قاعدة البيانات المقدَّم في وضع "مستودع البيانات"، ما يعني أنّه لا يمكن لحِزم تطوير البرامج (SDK) لمنصّة Firebase أو المصادقة أو Firebase Security Rules الوصول إليه. إذا كنت تريد استخدام Cloud Firestore مع خدمات Firebase هذه، عليك إفراغ قاعدة البيانات ثم تغيير نوع قاعدة البيانات في وحدة تحكّم Google Cloud.

عند توفير حزمة Cloud Storage التلقائية للمشروع (من خلال google_app_engine_application) ولم يكن للمشروع مثيل Cloud Firestore تلقائي بعد، يوفّر google_app_engine_application تلقائيًا مثيل Cloud Firestore التلقائي للمشروع.

وبما أنّه سبق أن تم توفير مثيل Cloud Firestore التلقائي لمشروعك، سيظهر خطأ في google_firestore_database إذا حاولت توفير هذا المثيل التلقائي مرة أخرى.

بعد توفير مثيل Cloud Firestore التلقائي للمشروع، لا يمكنك "إعادة توفيره" أو تغيير موقعه الجغرافي. يُرجى العِلم أنّ مثيل قاعدة البيانات التي تم توفيرها يكون في وضع Datastore، ما يعني أنّه لا يمكن الوصول إليه باستخدام حِزم تطوير البرامج (SDK) من Firebase أو المصادقة أو Firebase Security Rules. إذا كنت تريد استخدام Cloud Firestore مع خدمات Firebase هذه، عليك إفراغ قاعدة البيانات ثم تغيير نوع قاعدة البيانات في وحدة تحكّم Google Cloud.