افزونه‌های فایربیس را به یک کیت تابع خودساخته منتقل کنید

انتخاب مسیر مهاجرت: مهاجرت به کیت‌های تابع در npm مهاجرت به کیت تابع خودساخته

اگر ناشری کیت جایگزین رسمی توزیع‌شده روی npm ایجاد نکرده باشد، این راهنما شما را در مراحل ایجاد انشعاب از افزونه و تنظیم آن به عنوان یک کیت تابع محلی راهنمایی می‌کند.

محدودیت‌های مهاجرت شناخته‌شده را بررسی کنید

قبل از شروع انتقال یک نمونه افزونه، بررسی کنید که آیا تنظیمات شما از هر یک از ویژگی‌های زیر که نیاز به راه‌حل دارند یا هنوز در کیت‌های تابع پشتیبانی نمی‌شوند، استفاده می‌کند یا خیر:

  • مخازن سفارشی Docker و کلیدهای KMS نیاز به یک راه حل دستی دارند. Cloud Functions for Firebase از پارامترهای سیستم جایگزین برای پیکربندی یک مخزن سفارشی Docker یا کلید رمزگذاری مدیریت شده توسط مشتری (کلید KMS) پشتیبانی نمی‌کند. اگر افزونه شما هر یک از این پارامترها را پیکربندی می‌کند، به راه حل سوالات متداول مراجعه کنید.

قبل از اینکه شروع کنی

شما باید رابط خط فرمان Firebase CLI) را راه‌اندازی کرده و یک پروژه Firebase را راه‌اندازی اولیه کنید . هنگام استفاده از رابط خط فرمان، مطمئن شوید که firebase-tools نسخه >= 15.32.0 استفاده می‌کنید که دارای دستورات جدید migration و function kit است.

مجوزها و نقش‌های مورد نیاز حساب کاربری

بسته به آنچه که باید توسط Firebase CLI در طول مهاجرت ایجاد و پیکربندی شود، حسابی که برای تأیید اعتبار با Firebase و Google Cloud استفاده می‌کنید باید نقش‌های زیر را داشته باشد:

  • roles/firebaseextensions.editor
  • roles/cloudbuild.builds.editor
  • roles/artifactregistry.writer
  • roles/run.developer
  • roles/iam.serviceAccountUser
  • roles/iam.serviceAccountCreator
  • roles/cloudfunctions.admin (اگر نیاز به setIamPermissions برای نقاط انتهایی عمومی دارید)
  • roles/secretmanager.admin (در صورت استفاده از secretها)
  • roles/serviceusage.serviceUsageAdmin (اگر نیاز به فعال کردن API های جدید دارید)

توصیه می‌کنیم از حسابی استفاده کنید که قبلاً افزونه‌ها و توابع را نصب کرده باشد، زیرا اکثر این مجوزها از قبل اعطا شده‌اند. اگر حساب کاربری در حال انتقال شما به نقش‌های بیشتری نیاز دارد، دستورالعمل‌های Google Cloud IAM را برای اضافه کردن آنها دنبال کنید.

افزونه خود را به آخرین نسخه ارتقا دهید

شما باید افزونه خود را به آخرین نسخه به‌روزرسانی کنید تا تفاوت بین نمونه افزونه شما و کیت جایگزین آن به حداقل برسد. اگر افزونه شما ارتقا داده نشود، ممکن است تغییرات قابل توجه و مخربی بین نمونه افزونه شما و کیت جایگزین آن وجود داشته باشد. پیکربندی صادر شده ممکن است به دلیل تغییرات پارامترها در نسخه‌های مختلف، با آنچه کیت انتظار دارد مطابقت نداشته باشد.

بسته به محل نصب افزونه، از یکی از گزینه‌های زیر برای به‌روزرسانی آن استفاده کنید:

  • از کنسول Firebase
  • از رابط خط فرمان Firebase با استفاده از:
    • firebase ext:update <extension-instance-id> --project <project-id> firebase deploy --only extensions --project <project-id>

اگر از این مرحله صرف نظر کنید، رابط خط فرمان (CLI) هنگام خروجی گرفتن از پیکربندی، اگر افزونه شما آخرین نسخه نباشد، از شما می‌خواهد که آن را ارتقا دهید.

افزونه را به یک کیت تابع محلی تبدیل کنید

قبل از شروع تبدیل یک افزونه به یک کیت تابع محلی، مطمئن شوید که کد منبع افزونه درون پروژه Firebase شما قرار دارد. برای انجام این کار، مخزن افزونه را از GitHub کپی کنید، یک دایرکتوری درون ریشه پروژه Firebase خود ایجاد کنید و پوشه functions/ افزونه و extension.yaml در آن کپی کنید:

mkdir -p path/to/kit
cp -r /path/to/extension-source/functions/* path/to/kit/
cp /path/to/extension-source/extension.yaml path/to/kit/.

مراحل ۱ تا ۸ از راهنمای انتقال ناشر را دنبال کنید تا کد منبع افزونه خود را به یک تابع نسل دوم منتقل کنید. سپس مراحل زیر را ادامه دهید.

کیت محلی خود را طوری تنظیم کنید که از ناحیه تابع خروجی و پارامترهای پیشرفته پشتیبانی کند

در یک کیت تابع محلی، رابط خط فرمان Firebase فایل index.ts را برای راه‌اندازی بسته و پیکربندی آن برای استفاده از پارامترهای سیستم منتقل‌شده تولید نمی‌کند. برای استفاده از پارامترهای ناحیه تابع و پارامترهای پیشرفته که برای افزونه شما پیکربندی شده‌اند، فایل index.ts خود را طوری تنظیم کنید که فرمت صادر شده توسط firebase ext:export --mode functions در یک فایل متغیر محیطی بخواند.

به طور خاص، در فایل سطح بالای index.ts که توابع شما را اکسپورت می‌کند، یک پارامتر برای FUNCTION_DEFAULT_REGION تعریف کنید و setGlobalOptions با متغیرهای محیطی به شکل EXT_MIGRATED_SYSTEM_<GLOBAL_OPTION> فراخوانی کنید، مشابه الگوی index-kit-migration.ts که توسط CLI استفاده می‌شود:

import { setGlobalOptions } from "firebase-functions";
import { MemoryOption, VpcEgressSetting, IngressSetting } from "firebase-functions/v2/options";
import { defineString } from "firebase-functions/params";

export const regionParam = defineString("FUNCTION_DEFAULT_REGION", {
  input: { text: { nonEmpty: true } },
  description: "Global default region where functions should be deployed. Can be overridden per-function.",
});

setGlobalOptions({
  region: regionParam,
  memory: (process.env.EXT_MIGRATED_SYSTEM_MEMORY as MemoryOption) ?? undefined,
  timeoutSeconds: process.env.EXT_MIGRATED_SYSTEM_TIMEOUTSECONDS
    ? Number(process.env.EXT_MIGRATED_SYSTEM_TIMEOUTSECONDS)
    : undefined,
  vpcConnectorEgressSettings:
    process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS &&
    process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS !== "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED"
      ? (process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS as VpcEgressSetting)
      : undefined,
  vpcConnector: process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOR ?? undefined,
  maxInstances: process.env.EXT_MIGRATED_SYSTEM_MAXINSTANCES
    ? Number(process.env.EXT_MIGRATED_SYSTEM_MAXINSTANCES)
    : undefined,
  minInstances: process.env.EXT_MIGRATED_SYSTEM_MININSTANCES
    ? Number(process.env.EXT_MIGRATED_SYSTEM_MININSTANCES)
    : undefined,
  ingressSettings: (process.env.EXT_MIGRATED_SYSTEM_INGRESSSETTINGS as IngressSetting) ?? undefined,
  // Parses a comma-separated string of key:value pairs into a key-value object
  // (for example, "key1:value1,key2:value2" -> { key1: "value1", key2: "value2" }).
  labels: process.env.EXT_MIGRATED_SYSTEM_LABELS
    ? process.env.EXT_MIGRATED_SYSTEM_LABELS.split(",").reduce<Record<string, string> | undefined>(
        (acc, curr) => {
          const [key, value] = curr.split(":");
          const trimmedKey = key?.trim();
          const trimmedValue = value?.trim();
          if (!trimmedKey || !trimmedValue) {
            return acc;
          }
          acc = acc ?? {};
          acc[trimmedKey] = trimmedValue;
          return acc;
        },
        undefined,
      )
    : undefined,
});

// Re-export all functions so the Firebase CLI can deploy them
export * from "./your-functions";

قبل از مهاجرت، کیت خود را آزمایش کنید

اکنون یک کیت تابع محلی دارید که هنگام استقرار، دقیقاً مانند نصب جدید افزونه شما رفتار می‌کند. مرحله بعدی، تأیید و رفع هرگونه مشکلی است که به طور تصادفی در طول مسیر ایجاد می‌شود، قبل از اینکه نمونه‌های افزونه تولیدی خود را به آن منتقل کنید.

ابتدا، fork خود را به عنوان یک کیت محلی اضافه کنید، آن را پیکربندی کنید و در یک پروژه آزمایشی مستقر کنید. کیت‌های تابع محلی باید در داخل پروژه Firebase شما قرار داشته باشند، بنابراین اگر مخزن افزونه کلون شده خارج از پروژه Firebase شما است، آن را به داخل دایرکتوری پروژه منتقل کنید. سپس دستور نصب کیت زیر را اجرا کنید تا آن را به عنوان یک کیت محلی نصب کنید:

firebase functions:kits:install --directory <path-to-your-fork> --project <test-project-id>

این دستور شما را در انتخاب شناسه کیت، شناسه نمونه و پیکربندی برای اولین نمونه آزمایشی‌تان راهنمایی می‌کند. سپس فایل firebase.json شما را تغییر می‌دهد تا یک کیت محلی را که به دایرکتوری forked شما اشاره می‌کند، ثبت کند و پیکربندی‌های هر نمونه در یک فایل .env در مسیر function-kits/<kit-id>/config-<instance-id> ذخیره شود.

کیت محلی خود را در یک پروژه آزمایشی با منابع مناسب برای آزمایش رفتار آن مستقر کنید. اگر از قبل یک پروژه آزمایشی از آزمایش افزونه خود راه‌اندازی کرده‌اید، دستور زیر را اجرا کنید:

firebase deploy --only functions:<kit-instance-id> --project <test-project-id>

مثال عملی: انتقال Cloud Firestore به BigQuery ( firestore-bigquery-export )

تأیید کنید که Cloud Firestore با BigQuery به صورت سرتاسری همگام‌سازی می‌شود:

  1. در صفحه Cloud Firestore کنسول Firebase ، اگر مجموعه‌ای که به عنوان COLLECTION_PATH ( users ) تنظیم کرده‌اید از قبل وجود ندارد، آن را ایجاد کنید.
  2. یک سند با نام bigquery-mirror-test ایجاد کنید که شامل هر فیلدی با هر مقداری باشد.
  3. در صفحه BigQuery کنسول Google Cloud ، جدول خام گزارش تغییرات را جستجو کنید. این جدول باید شامل یک ردیف باشد که ایجاد سند را ثبت می‌کند:

    SELECT * FROM `PROJECT_ID.analytics.users_raw_changelog`
    
  4. آخرین نمای (view) را کوئری کنید، که باید آخرین رویداد تغییر را برای تنها سند موجود برگرداند ( bigquery-mirror-test ):

    SELECT * FROM `PROJECT_ID.analytics.users_raw_latest`
    
  5. سند bigquery-mirror-test را در Cloud Firestore حذف کنید. این سند از آخرین نمای نمایش داده شده ناپدید می‌شود و یک رویداد DELETE به جدول خام گزارش تغییرات اضافه می‌شود.

    شما می‌توانید تاریخچه کامل یک سند را با استفاده از موارد زیر بررسی کنید:

    SELECT *
       FROM `PROJECT_ID.analytics.users_raw_changelog`
       WHERE document_name = "bigquery-mirror-test"
       ORDER BY timestamp ASC
    

تفاوت‌های حاصل از آزمایش افزونه:

  • تریگر به صورت kit-<kit-instance-id>-fsexportbigquery مستقر می‌شود، نه ext-<instanceId>-fsexportbigquery . آن نام را در داشبورد و گزارش‌های Cloud Functions جستجو کنید.
  • کد شما در Firebase Local Emulator Suite به عنوان توابع استاندارد اجرا می‌شود. می‌توانید مقادیر پارامترها را برای استفاده در شبیه‌ساز با .env.local تنظیم کنید. همچنین می‌توانید کد خود را با استفاده از firebase-functions-test SDK همانطور که در بخش تست واحد Cloud Functions توضیح داده شده است، تست واحد کنید.
  • تأمین منابع دیگر توسط زمان اجرای Extensions هدایت نمی‌شود. اگر جدول گزارش تغییرات پس از استقرار از دست رفته باشد، وظیفه راه‌اندازی را به صورت دستی دوباره اجرا کنید: firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id> . این وظیفه خودتوان است، بنابراین اجرای مجدد آن، مجموعه داده‌ها، جدول و نماها را تطبیق می‌دهد.
  • مقادیر پارامتر به جای فرم نصب، از .env ‎ می‌آیند، بنابراین اجرای مجدد firebase deploy پس از تکمیل فایل .env ‎ غیرتعاملی خواهد بود.

(اختیاری) پاکسازی از آزمایش

اگر می‌خواهید این نمونه آزمایشی را پس از آزمایش حذف کنید، آن را حذف نصب کنید:

firebase functions:kits:uninstall --instance <kit-instance-id> --project <test-project-id>

این کار تمام منابع ابری ایجاد شده توسط استقرار کیت و پیکربندی نمونه آن را حذف می‌کند. اگر فقط یک نمونه از کیت دارید، ورودی کیت را از firebase.json نیز حذف می‌کند. این کار دایرکتوری کد منبع محلی شما را حذف نمی‌کند. هنگام نصب کیت برای مهاجرت به محیط عملیاتی، می‌توانید دوباره یک شناسه کیت انتخاب کنید.

از افزونه‌ها به کیت محلی خود مهاجرت کنید

اکنون که کیت محلی شما آزمایش شده است، می‌توانید نمونه افزونه مستقر شده زنده خود را منتقل کنید.

۱. نمونه کیت تابع جایگزین را نصب کنید

کیت تابع محلی خود را نصب کنید، و برای رد شدن از پیکربندی دستی، از --no-configure استفاده کنید تا در مرحله بعدی بتوانید پیکربندی افزونه موجود خود را مستقیماً به این نمونه کیت صادر کنید:

firebase functions:kits:install --no-configure --directory <path-to-your-fork> --project <project-id>

۲. نمونه کیت تابع را دقیقاً مشابه افزونه پیکربندی کنید

شما باید این نمونه کیت را با پیکربندی مشابه افزونه‌ای که جایگزین آن می‌شود، سفارشی‌سازی کنید. می‌توانید پیکربندی نمونه افزونه خود را در یک فایل .env اکسپورت کنید، که پارامترها، متغیرهای محیطی و داده‌های پیکربندی مرجع مخفی را برای همه Cloud Functions ، از جمله کیت‌ها، ذخیره می‌کند. برای اکسپورت مستقیم آن به فایل پیکربندی کیت خود، دستور زیر را اجرا کنید:

firebase ext:export --mode functions --instance <extension-instance-id> --kit-instance <kit-instance-id> --project <project-id>

در پایان این مرحله، اطلاعات پیکربندی این نمونه در یک فایل .env مخصوص پروژه در دایرکتوری پیکربندی نمونه شما ذخیره می‌شود، مانند: function-kits/<kit-name>/config-<instance-id>/.env.<project-id>

۳. کیت جایگزین را مستقر و تأیید کنید

اکنون که کیت نصب شده و به عنوان مجموعه‌ای از توابع در دسترس است، می‌توانید جایگزین کیت را مستقر کنید. کیت‌های تابع مانند توابع استاندارد کار می‌کنند، که در آن هر نمونه کیت به عنوان یک پایگاه کد جداگانه برای سازماندهی توابع شما عمل می‌کند. می‌توانید انتخاب کنید که تمام توابع خود یا فقط یک نمونه کیت خاص را مستقر کنید. هنگام مهاجرت یک نمونه افزونه، فقط آن نمونه کیت را مستقر کنید.

اگر کیت شما از پارامترهای جدیدی استفاده کند که در نمونه افزونه‌ای که از آن مهاجرت کرده‌اید وجود نداشته‌اند، رابط خط فرمان Firebase در ابتدای فرآیند استقرار، آن‌ها را از شما درخواست می‌کند. در این مثال کاربردی از یک افزونه به‌روز firestore-bigquery-export ، انتظار نمی‌رود که این اتفاق بیفتد، اما بسیاری از کیت‌ها برای هر منبع رویدادی که توسط کیت استفاده می‌شود، پارامتر جدیدی را درخواست می‌کنند. به عنوان بخشی از این مهاجرت، کیت‌های به‌روز شده از توابع نسل دوم استفاده می‌کنند، در حالی که افزونه‌ها قبلاً از توابع نسل اول استفاده می‌کردند. در نسل دوم، توابع در نزدیکی منابع رویداد خود قرار دارند و به عنوان یک پارامتر اضافی اضافه می‌شوند. در به‌روزرسانی‌های بعدی، اگر پارامترهای جدیدی اضافه شوند، رابط خط فرمان در مورد استقرار بعدی به شما اطلاع می‌دهد.

مثال کار شده:

firebase deploy --only functions:firestore-bigquery-export --project my-project

خروجی:

=== Deploying to 'my-project'...
i  deploying functions
i  functions: Loaded environment variables from function-kits/firestore-bigquery-export/config-firestore-bigquery-export/.env.my-project
i  functions: ensuring required API bigquery.googleapis.com is enabled...
i  functions: ensuring required API cloudtasks.googleapis.com is enabled...
✔  functions: required APIs are enabled
i  functions: granting declarative IAM roles to managed service account:
   - BigQuery Data Editor
   - BigQuery User
   - Cloud Datastore User
   - Eventarc Event Receiver
   - roles/run.invoker
✔  functions: successfully granted IAM roles
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-fsexportbigquery(us-central1)...
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-initBigQuerySync(us-central1)...
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-setupBigQuerySync(us-central1)...
✔  functions[kit-firestore-bigquery-export-fsexportbigquery(us-central1)] Successful create operation.
✔  functions[kit-firestore-bigquery-export-initBigQuerySync(us-central1)] Successful create operation.
✔  functions[kit-firestore-bigquery-export-setupBigQuerySync(us-central1)] Successful create operation.
i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/us-central1/queues/kit-firestore-bigquery-export-initBigQuerySync.
✔  Deploy complete!

برای تأیید اینکه firebase deploy کیت هیچ خطایی نداشته است، گزارش‌های استقرار را بررسی کنید تا ببینید آیا قلاب‌های چرخه عمر فعال شده‌اند یا خیر. افزونه‌های محبوب، مانند Stream Cloud Firestore به BigQuery ، از قلاب‌های چرخه عمر استفاده می‌کنند. در زیر مثالی از نحوه نمایش یک قلاب چرخه عمر هنگام فعال شدن آمده است:

i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/europe-west1/queues/kit-firestore-bigquery-export-initBigQuerySync.
i  functions: View logs for afterFirstDeploy at: https://console.cloud.google.com/logs/query;query=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22kit-firestore-bigquery-export--initbigquerysync%22%0Aresource.labels.location%3D%22europe-west1%22;project=my-project

این پیام‌های لاگ موارد زیر را تأیید می‌کنند:

  • یک قلاب چرخه عمر پیدا و اجرا شد.
  • یک وظیفه در صف وظیفه مرتبط با قلاب چرخه عمر قرار گرفته است.
  • پیوندی به Cloud Logging ارائه شده است تا بتوانید تأیید کنید که کار بدون خطا انجام شده است.

برای تأیید اینکه هیچ خطایی در گزارش‌ها وجود ندارد و رویداد صف وظایف شما با موفقیت پردازش شده است، پیوند گزارش‌ها را به کنسول Google Cloud دنبال کنید. اگر رویداد چرخه عمر با موفقیت اجرا نشد، می‌توانید با اجرای دستور زیر آن را دوباره فعال کنید:

firebase functions:lifecycle:run <hook-name> <codebase>

اگر برای اولین بار است که یک نمونه کیت تابع را مستقر می‌کنید، دستور زیر را اجرا کنید:

firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id>

اگر در هر زمانی در طول اعتبارسنجی تصمیم گرفتید که این مهاجرت را متوقف یا لغو کنید، می‌توانید کیت را با استفاده از دستورالعمل‌های موجود در بخش «حذف افزونه» حذف نصب کنید.

۴. افزونه را حذف نصب کنید

وقتی کیت تابع پیاده‌سازی‌شده‌ی خود را تأیید کردید، می‌توانید افزونه‌ی خود را حذف نصب کنید تا رفتار آن را یک بار برای کیت و یک بار برای افزونه تکرار نکنید. می‌توانید تمام افزونه‌ها را از رابط خط فرمان Firebase ، صرف نظر از نحوه‌ی نصب آنها، حذف نصب کنید، اگر پرچم --immediate پاس دهید:

firebase ext:uninstall <extension-instance-id> --project <project-id> --immediate

مثال کار شده:

firebase ext:uninstall firestore-bigquery-export --project my-project --immediate

خروجی:

i  extensions: uninstalling firestore-bigquery-export...
i  extensions: deleting extension instance resources in project my-project...
✔  extensions: successfully uninstalled firestore-bigquery-export

مهاجرت‌های پیشرفته

شما می‌توانید افزونه‌هایی را در چندین پروژه Firebase داشته باشید که می‌خواهید با یک کدبیس واحد مدیریت کنید. برای مثال، اگر زیرساخت یکسانی را در یک محیط testing و یک محیط production مستقر کنید، که هر کدام یک نمونه documents Cloud Firestore دارند که به BigQuery صادر می‌کنید، ممکن است دو نمونه از افزونه firestore-bigquery-export نصب شده داشته باشید:

  • export-documents-testing
  • export-documents-production

اگر هنگام کار با Firebase CLI، این دو نمونه افزونه را به دو نمونه کیت تابع در یک کدبیس واحد منتقل کرده و با استفاده از firebase deploy --project testing و firebase deploy --project production مستقر کرده باشید، هر استقرار، دو نمونه در محیط‌های testing و production ایجاد می‌کند.

در عوض، دو نمونه افزونه را با یک نمونه کیت تابع از firestore-bigquery-export که در چندین پروژه مستقر شده است، جایگزین کنید، که در آن هر پروژه پیکربندی خاص خود را دارد. دایرکتوری پیکربندی شما برای این نمونه باید مانند زیر باشد:

  • config-export-documents/
    • .env.testing
    • .env.production

هر بار که کیت شما برای testing و production آماده می‌شود، یک نمونه از آن با پیکربندی مربوطه ایجاد می‌شود. دستورات CLI موجود، مادامی که در هر فراخوانی ext:migrate یا functions:kits:install ، پرچم --project را وارد کنید، این تنظیمات را ایجاد می‌کنند.

مثال کار شده:

firebase functions:kits:install --package @firebase-function-kits/firestore-bigquery-export --project testing --no-configure --template migration
✔ What would you like to name this kit? firestore-bigquery-export
✔ What would you like to name this instance? export-documents
✔  Wrote function-kits/firestore-bigquery-export/source/package.json
✔  Wrote function-kits/firestore-bigquery-export/source/tsconfig.json
✔  Wrote function-kits/firestore-bigquery-export/source/.gitignore
✔  Wrote function-kits/firestore-bigquery-export/source/src/index.ts
i  functions: Running npm install
✔  Wrote configuration info to firebase.json
✔  functions: Function kit firestore-bigquery-export successfully installed.
# This creates the export-documents instance with an empty .env.testing file
# for the testing project. Now populate it via export:
firebase ext:export --mode functions --instance export-documents-testing \
  --kit-instance export-documents --project testing

# Repeat the export for production into the same kit instance to create
# .env.production from the export-documents-prod instance:
firebase ext:export --mode functions --instance export-documents-prod \
  --kit-instance export-documents --project production

اکنون یک نمونه کیت واحد دارید که برای استقرار در پروژه‌های testing و production شما با پیکربندی‌های مربوطه پیکربندی شده است. اگر یک نمونه در پروژه testing ایجاد کنید و دستور functions:kits:install را برای همان بسته در پروژه production اجرا کنید، از شما خواسته می‌شود که از نمونه پیکربندی شده برای testing دوباره استفاده کنید یا یک نمونه دوم نصب کنید.