Как настроить несколько проектов

На этой странице рассказывается, как использовать в приложении несколько проектов Firebase.

Для большинства приложений достаточно одного проекта Firebase и настроек по умолчанию, описанных в руководствах по началу работы. Примеры ситуаций, в которых может быть полезно использовать несколько проектов Firebase:

  • Настройка среды разработки для использования разных проектов Firebase в зависимости от типа сборки или целевой платформы.
  • Доступ к контенту из нескольких проектов Firebase в приложении.

Поддержка разных сред

Один из распространенных вариантов использования – поддержка отдельных проектов Firebase для сред разработки и выпуска.

SDK для веб-сайтов и администраторов настраиваются путем передачи значений непосредственно в функции инициализации. В этих SDK можно использовать проверку во время выполнения, чтобы выбирать переменные конфигурации для разработки или производства.

Платформы Android и Apple (и их оболочки Unity и C++) обычно загружают конфигурацию из файла конфигурации: GoogleService-Info.plist на платформе Apple и google-services.json на Android. Эти файлы считываются в объект options (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-services. Узнайте, какие ресурсы создает плагин, в разделе Как обрабатывается файл конфигурации JSON.

Вы можете создать файл конфигурации google-services.json для каждого варианта сборки, поместив каждый файл google-services.json в отдельный каталог, названный в честь варианта сборки, в корневом каталоге модуля приложения. Например, если у вас есть варианты сборки "development" и "release", конфигурация может выглядеть так:

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

Подробнее о том, как добавить файл JSON…

Эти ресурсы загружаются FirebaseInitProvider, который запускается до кода приложения и инициализирует API Firebase, используя эти значения.

Поскольку этот поставщик просто считывает ресурсы с известными названиями, вы можете добавить строковые ресурсы непосредственно в приложение, а не использовать плагин Gradle google-services. Например:

  • Удаление плагина Gradle google-services из корневого файла build.gradle
  • Удаление файла конфигурации google-services.json из проекта
  • Добавление строковых ресурсов напрямую
  • Удаление apply plugin: 'com.google.gms.google-services' из приложения "build.gradle"

Как использовать несколько проектов в приложении

Иногда вам нужно получить доступ к разным проектам с помощью одних и тех же API, например к нескольким экземплярам базы данных. В большинстве случаев существует центральный объект приложения Firebase, который управляет конфигурацией всех API Firebase. Этот объект инициализируется в рамках обычной настройки. Однако, если вы хотите получить доступ к нескольким проектам из одного приложения, вам понадобится отдельный объект приложения Firebase для каждого из них. Инициализировать другие экземпляры должны вы.

В обоих случаях сначала нужно создать объект параметров Firebase, в котором будут храниться данные конфигурации приложения Firebase. Полную документацию по этим параметрам можно найти в справочной документации по API для следующих классов:

Ниже приведены примеры использования этих классов для поддержки нескольких проектов в приложении.

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 (API для других функций 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 и запрашиваете объявления при запуске, как рекомендуется, то при отсутствии конфигурации на основе ресурсов можете потерять некоторые данные Аналитики, связанные с мобильными объявлениями.
  2. В каждом варианте приложения, который вы распространяете, должен быть только один идентификатор приложения Google. Например, если вы выпустили версию 1 приложения с определенным идентификатором GOOGLE_APP_ID в конфигурации, а затем загрузили версию 2 с другим идентификатором, это может привести к потере данных аналитики.
  3. На платформах Apple не добавляйте файл GoogleService-Info.plist в проект, если вы предоставляете другую конфигурацию во время выполнения, так как это может привести к очевидным изменениям GOOGLE_APP_ID и потере данных Аналитики.