إعداد مشاريع متعددة

توضّح هذه الصفحة كيفية استخدام أكثر من مشروع Firebase واحد في تطبيقك.

لا تحتاج العديد من التطبيقات سوى إلى مشروع واحد على Firebase والإعداد التلقائي الموضّح في أدلة البدء. في ما يلي أمثلة على الحالات التي يمكن أن يكون فيها استخدام مشاريع متعددة على Firebase مفيدًا:

  • إعداد بيئة التطوير لاستخدام مشاريع Firebase مختلفة استنادًا إلى نوع التصميم أو الهدف
  • الوصول إلى المحتوى من مشاريع متعدّدة على Firebase في تطبيقك

إتاحة بيئات مختلفة

من حالات الاستخدام الشائعة إتاحة مشاريع منفصلة على Firebase لبيئتَي التطوير والإصدار العلني.

يتم ضبط حزمتَي تطوير البرامج (SDK) على الويب وSDK للمشرف من خلال تمرير القيم مباشرةً إلى دوال الإعداد. بالنسبة إلى حِزم SDK هذه، يمكنك استخدام عملية تحقّق في وقت التشغيل لاختيار متغيرات الضبط الخاصة بالتطوير أو الإنتاج.

تحمّل منصّتا Android وApple (وبرامج التغليف Unity وC++ الخاصة بهما) عادةً إعدادات من ملف إعداد: GoogleService-Info.plist على منصّة Apple وgoogle-services.json على Android. تتم قراءة هذه الملفات في عنصر خيارات (FIROption أو FirebaseOptions) تتم الإشارة إليه من خلال عنصر تطبيق Firebase (FIRApp أو FirebaseApp).

في هذه الأنظمة الأساسية، يتم عادةً تنفيذ التبديل بين البيئات كقرار يتم اتخاذه في مدّة التصميم، وذلك من خلال استخدام ملفات إعداد مختلفة لكل بيئة.

توفير بيئات متعددة في تطبيق Apple

بشكل تلقائي، سيحمّل FirebaseApp.configure() الملف GoogleService-Info.plist المضمّن في التطبيق. إذا تم ضبط بيئتَي التطوير والإنتاج كهدفَين منفصلَين في Xcode، يمكنك إجراء ما يلي:

  • تنزيل كلا الملفين (GoogleService-Info.plist)
  • تخزين الملفَين في دليلَين مختلفَين
  • إضافة كليهما إلى مشروع Xcode
  • اربط الملفات المختلفة بالأهداف المختلفة باستخدام لوحة Target Membership (عضوية الهدف):

لوحة "العضوية المستهدَفة"

إذا كانت الإصدارات جزءًا من هدف واحد، فإنّ الخيار الأفضل هو منح ملفَي الإعداد اسمَين فريدَين (مثل GoogleService-Info-Free.plist وGoogleService-Info-Paid.plist)، ثم اختيار ملف plist الذي سيتم تحميله في وقت التشغيل. يظهر ذلك في المثال التالي:

// Load a named file.
guard 
  let filePath = Bundle.main.path(forResource: "MyGoogleService", ofType: "plist"),
  let fileOptions = FirebaseOptions(contentsOfFile: filePath)
else { fatalError("Couldn't load config file.") }
FirebaseApp.configure(options: fileOptions)

إتاحة بيئات متعددة في تطبيق Android

في نظام التشغيل Android، تتم معالجة ملف google-services.json وتحويله إلى موارد سلاسل Android باستخدام المكوّن الإضافي لنظام Gradle المتوافق مع "خدمات Google". يمكنك الاطّلاع على المراجع التي تم إنشاؤها في مستندات المكوّن الإضافي في "خدمات Google" ضمن معالجة ملف JSON.

يمكنك الحصول على ملفات google-services.json متعددة لتنويعات تصميم مختلفة عن طريق وضع ملفات google-services.json في أدلة مخصّصة تحمل اسم كل تنويعة ضمن جذر وحدة التطبيق. على سبيل المثال، إذا كان لديك نوعا الإصدار "development" و"release"، يمكن تنظيم الإعدادات على النحو التالي:

app/
    google-services.json
    src/development/google-services.json
    src/release/google-services.json
    ...

لمزيد من المعلومات، راجِع مستندات المكوّن الإضافي في "خدمات Google" حول إضافة ملف JSON.

بعد ذلك، يتم تحميل هذه الموارد بواسطة FirebaseInitProvider، الذي يتم تنفيذه قبل الرمز البرمجي لتطبيقك ويعمل على تهيئة واجهات برمجة تطبيقات Firebase باستخدام هذه القيم.

بما أنّ هذا الموفّر يقرأ الموارد التي تحمل أسماء معروفة فقط، يمكنك إضافة موارد السلسلة مباشرةً إلى تطبيقك بدلاً من استخدام المكوّن الإضافي Google Services Gradle. يمكنك إجراء ذلك من خلال:

  • إزالة المكوّن الإضافي google-services من build.gradle الجذر
  • حذف google-services.json من مشروعك
  • إضافة موارد السلسلة مباشرةً
  • حذف apply plugin: 'com.google.gms.google-services' من تطبيقك build.gradle

استخدام مشاريع متعددة في تطبيقك

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

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

يتم عرض استخدام هذه الفئات لتوفير الدعم لمشاريع متعددة في تطبيق في الأمثلة التالية:

Swift

// Configure with manual options. Note that projectID and apiKey, though not
// required by the initializer, are mandatory.
let secondaryOptions = FirebaseOptions(googleAppID: "1:27992087142:ios:2a4732a34787067a",
                                       gcmSenderID: "27992087142")
secondaryOptions.apiKey = "AIzaSyBicqfAZPvMgC7NZkjayUEsrepxuXzZDsk"
secondaryOptions.projectID = "projectid-12345"

// The other options are not mandatory, but may be required
// for specific Firebase products.
secondaryOptions.bundleID = "com.google.firebase.devrel.FiroptionConfiguration"
secondaryOptions.clientID = "27992087142-ola6qe637ulk8780vl8mo5vogegkm23n.apps.googleusercontent.com"
secondaryOptions.databaseURL = "https://myproject.firebaseio.com"
secondaryOptions.storageBucket = "myproject.appspot.com"
secondaryOptions.deepLinkURLScheme = "myapp://"
secondaryOptions.storageBucket = "projectid-12345.appspot.com"
secondaryOptions.appGroupID = nil

Kotlin

// Manually configure Firebase Options. The following fields are REQUIRED:
//   - Project ID
//   - App ID
//   - API Key
val options = FirebaseOptions.Builder()
    .setProjectId("my-firebase-project")
    .setApplicationId("1:27992087142:android:ce3b6448250083d1")
    .setApiKey("AIzaSyADUe90ULnQDuGShD9W23RDP0xmeDc6Mvw")
    // .setDatabaseUrl(...)
    // .setStorageBucket(...)
    .build()

Java

// Manually configure Firebase Options. The following fields are REQUIRED:
//   - Project ID
//   - App ID
//   - API Key
FirebaseOptions options = new FirebaseOptions.Builder()
        .setProjectId("my-firebase-project")
        .setApplicationId("1:27992087142:android:ce3b6448250083d1")
        .setApiKey("AIzaSyADUe90ULnQDuGShD9W23RDP0xmeDc6Mvw")
        // setDatabaseURL(...)
        // setStorageBucket(...)
        .build();

الويب

// The following fields are REQUIRED:
//  - Project ID
//  - App ID
//  - API Key
const secondaryAppConfig = {
    projectId: "<PROJECT_ID>",
    appId: "<APP_ID>",
    apiKey: "<API_KEY>",
    // databaseURL: "...",
    // storageBucket: "...",
};

C++‎

firebase::AppOptions secondary_app_options;

// API key, app ID, and project ID are always required.
secondary_app_options.set_api_key("<API_KEY>");
secondary_app_options.set_app_id("<GOOGLE_APP_ID>");
secondary_app_options.set_project_id("<PROJECT_ID>");

// The following options are specific to individual Firebase products
// and may not always be required.
secondary_app_options.set_database_url("<DATABASE_URL>");
secondary_app_options.set_messaging_sender_id("<SENDER_ID>");
secondary_app_options.set_storage_bucket("<STORAGE_BUCKET>");

Unity

Firebase.AppOptions secondaryAppOptions = new Firebase.AppOptions {
  ApiKey = "<API_KEY>",
  AppId = "<GOOGLE_APP_ID>",
  ProjectId = "<PROJECT_ID>"
};

Node.js

const secondaryServiceAccount = require('./path/to/serviceAccountKey.json');

// All required options are specified by the service account,
// add service-specific configuration like databaseURL as needed.
const secondaryAppConfig = {
    credential: cert(secondaryServiceAccount),
    // databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
};

Java

FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");

FirebaseOptions secondaryAppConfig = new FirebaseOptions.Builder()
  .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
  .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
  .build();

بعد إعداد عنصر الخيارات هذا، يمكنك استخدامه لإعداد مثيل إضافي لتطبيق Firebase. يُرجى العِلم أنّنا نستخدم السلسلة secondary في جميع الأمثلة الموضّحة أدناه. يُستخدَم هذا الاسم لاسترداد مثيل التطبيق وتمييزه عن المثيلات الأخرى، بما في ذلك المثيل التلقائي (المسمّى [DEFAULT]). يجب اختيار سلسلة مناسبة للاستخدام المقصود لمشروع Firebase الآخر.

توضّح المقتطفات التالية كيفية الاتصال بـ Realtime Database بديل (تتّبع واجهات برمجة التطبيقات لميزات Firebase الأخرى النمط نفسه).

Swift

// Configure an alternative FIRApp.
FirebaseApp.configure(name: "secondary", options: secondaryOptions)

// Retrieve a previous created named app.
guard let secondary = FirebaseApp.app(name: "secondary")
  else { fatalError("Could not retrieve secondary app") }


// Retrieve a Real Time Database client configured against a specific app.
let secondaryDb = Database.database(app: secondary)

Kotlin

// Initialize secondary FirebaseApp.
Firebase.initialize(context = this, options, "secondary")

// Retrieve secondary FirebaseApp.
val secondary = Firebase.app("secondary")
// Get the database for the other app.
val secondaryDatabase = Firebase.database(secondary)

Java

// Initialize with secondary app
FirebaseApp.initializeApp(this /* Context */, options, "secondary");

// Retrieve secondary FirebaseApp
FirebaseApp secondary = FirebaseApp.getInstance("secondary");

الويب

// Initialize another app with a different config
const secondaryApp = firebase.initializeApp(secondaryAppConfig, "secondary");
// Access services, such as the Realtime Database
// secondaryApp.database();

C++‎

firebase::App* secondary_app = firebase::App::Create(secondary_app_options, "Secondary");
firebase::database::Database* secondary_database = firebase::database::Database::GetInstance(secondary_app);

Unity

var secondaryApp = Firebase.FirebaseApp.Create(secondaryAppOptions, "Secondary"));
var secondaryDatabase = Firebase.Database.FirebaseDatabase.getInstance(secondaryApp);

Node.js

// Initialize another app with a different config
const secondary = initializeApp(secondaryAppConfig, 'secondary');
// Access services, such as the Realtime Database
// const secondaryDatabase = secondary.database();

Java

// Initialize another app with a different config
FirebaseApp secondaryApp = FirebaseApp.initializeApp(secondaryAppConfig, "secondary");

// Retrieve the database.
FirebaseDatabase secondaryDatabase = FirebaseDatabase.getInstance(secondaryApp);

ضمان إعداد تقارير موثوقة بشأن "Analytics"

تجمع Google Analytics الأحداث في وقت مبكر جدًا من عملية بدء تشغيل التطبيق، وفي بعض الأحيان قبل إعداد مثيل تطبيق Firebase الأساسي. في هذه الحالات، يشير Firebase إلى مصدر Android أو GoogleService-Info.plist على منصات Apple للبحث عن رقم تعريف تطبيق Google الصحيح لتخزين الأحداث. لهذا السبب، ننصحك باستخدام طرق الإعداد التلقائية حيثما أمكن ذلك.

إذا كان إعداد وقت التشغيل مطلوبًا، يُرجى ملاحظة التحذيرات التالية:

  1. إذا كنت تستخدم AdMob وطلبت عرض الإعلانات عند بدء التشغيل كما هو مقترَح، قد تفوتك بعض بيانات &quot;إحصاءات Google&quot; ذات الصلة بالإعلانات على الأجهزة الجوّالة عند عدم استخدام أسلوب الإعداد المستند إلى الموارد.
  2. يجب عدم تقديم سوى معرّف واحد لتطبيق Google في كل صيغة موزَّعة من تطبيقك. على سبيل المثال، إذا أرسلت الإصدار 1 من تطبيقك مع GOOGLE_APP_ID معيّن في الإعدادات ثم حمّلت الإصدار 2 بمعرّف مختلف، قد يؤدي ذلك إلى فقدان بيانات الإحصاءات.
  3. على منصات Apple، لا تُضِف ملف GoogleService-Info.plist إلى مشروعك إذا كنت توفّر إعدادات مختلفة في وقت التشغيل، لأنّ ذلك قد يؤدي إلى تغيير واضح في GOOGLE_APP_ID وإلى فقدان بيانات "إحصاءات Google".