Configura varios proyectos

En esta página se describe cómo usar más de un proyecto de Firebase en tu app.

Muchas apps solo necesitan un proyecto de Firebase y la configuración predeterminada que se describe en las guías de introducción. Entre los ejemplos de casos en los que puede ser útil usar varios proyectos de Firebase, se incluyen los siguientes:

  • La configuración del entorno de desarrollo para usar diferentes proyectos de Firebase a partir del tipo de compilación o el objetivo
  • Acceso al contenido de varios proyectos de Firebase en la app

Compatibilidad con diferentes entornos

Un caso de uso común es tener proyectos de Firebase independientes para los entornos de desarrollo y producción.

Los SDK web y de Admin se configuran pasando valores directamente a sus funciones de inicialización. En estos SDK, puedes usar una verificación de tiempo de ejecución para seleccionar variables de configuración de desarrollo o de producción.

Las plataformas de Android y Apple (y sus wrappers de Unity y C++) suelen cargar la configuración desde un archivo de configuración: GoogleService-Info.plist en la plataforma de Apple y google-services.json en Android. Estos archivos se leen en un objeto de opciones (FIROption o FirebaseOptions) al que hace referencia el objeto de la aplicación de Firebase (FIRApp o FirebaseApp).

Para estas plataformas, el cambio de un entorno a otro se implementa, por lo general, como una decisión en el tiempo de compilación, mediante el uso de distintos archivos de configuración para cada entorno.

Compatibilidad con varios entornos en tu aplicación para Apple

De forma predeterminada, FirebaseApp.configure() cargará el archivo GoogleService-Info.plist que se incluye con la aplicación. Si tus entornos de desarrollo y producción están configurados como diferentes objetivos en Xcode, puedes hacer lo siguiente:

  • Descargar ambos archivos GoogleService-Info.plist
  • Almacenarlos en directorios diferentes
  • Agregar ambos a tu proyecto Xcode
  • Asociar los archivos correspondientes con los diferentes objetivos en el panel Target Membership:

Panel Target Membership

Si las compilaciones corresponden a un solo objetivo, la mejor opción es definir un nombre distinto para cada archivo de configuración (p. ej., GoogleService-Info-Free.plist y GoogleService-Info-Paid.plist). Luego, en el tiempo de ejecución, elige qué plist deseas cargar. Esto se muestra en el siguiente ejemplo:

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

Compatibilidad con varios entornos en tu aplicación para Android

En Android, el complemento de Gradle de Google Services procesa el archivo google-services.json en recursos de cadenas de Android. Puedes ver qué recursos se crean en la documentación del complemento de Google Services, en la sección sobre cómo procesar el archivo JSON.

Puedes tener varios archivos google-services.json para diferentes variantes de compilación si colocas archivos google-services.json en directorios independientes que tengan el nombre de cada variante en la raíz del módulo de la app. Por ejemplo, si tienes las variantes de compilación “development” y “release”, puedes organizar la configuración de la siguiente manera:

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

Para obtener más información, consulta la documentación del complemento de Google Services en cómo agregar el archivo JSON.

Luego, el FirebaseInitProvider, que se ejecuta antes que el código de tu aplicación y después inicializa las APIs de Firebase con esos valores, carga estos recursos.

Debido a que este proveedor simplemente lee los recursos con un nombre conocido, otra opción es agregar los recursos de cadenas directamente a tu app en lugar de usar el complemento de Gradle de Google Services. Para ello, tienes las siguientes opciones:

  • Quitar el complemento google-services del build.gradle raíz
  • Borrar el archivo google-services.json del proyecto
  • Agregar los recursos de cadenas directamente
  • Borrar apply plugin: 'com.google.gms.google-services' del build.gradle de la app

Usa varios proyectos en tu aplicación

A veces necesitas acceder a diferentes proyectos con las mismas APIs; por ejemplo, para consultar varias instancias de bases de datos. En la mayoría de los casos, hay un objeto de aplicación central de Firebase que administra la configuración de todas las APIs de Firebase. Este objeto se inicializa como parte de tu configuración normal. Sin embargo, cuando quieras tener acceso a varios proyectos desde una sola aplicación, necesitarás un objeto de aplicación de Firebase independiente para hacer referencia a cada uno de manera individual. La decisión de inicializar estas otras instancias depende de ti.

En ambos casos, primero necesitas crear un objeto de opciones de Firebase que contenga los datos de configuración de la aplicación de Firebase. Puedes encontrar la documentación completa sobre estas opciones en la documentación de referencia de la API para las siguientes clases:

En los siguientes ejemplos, se muestra cómo usar estas clases para trabajar con varios proyectos en una aplicación:

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.trackingID = "UA-12345678-1"
secondaryOptions.clientID = "27992087142-ola6qe637ulk8780vl8mo5vogegkm23n.apps.googleusercontent.com"
secondaryOptions.databaseURL = "https://myproject.firebaseio.com"
secondaryOptions.storageBucket = "myproject.appspot.com"
secondaryOptions.androidClientID = "12345.apps.googleusercontent.com"
secondaryOptions.deepLinkURLScheme = "myapp://"
secondaryOptions.storageBucket = "projectid-12345.appspot.com"
secondaryOptions.appGroupID = nil

Kotlin+KTX

// 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();

Web

// 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();

Después de inicializar este objeto de opciones, puedes usarlo para configurar una instancia adicional de una aplicación de Firebase. Ten en cuenta que, en todos los ejemplos que se muestran a continuación, usamos la cadena secondary. Este nombre se usa para recuperar la instancia de la aplicación y distinguirla de otras, incluida la instancia predeterminada (llamada [DEFAULT]). Debes elegir una cadena adecuada según el uso que deseas darle al otro proyecto de Firebase.

Los siguientes fragmentos demuestran la conexión a una Realtime Database alternativa (las APIs para otras funciones de Firebase siguen el mismo patrón).

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 { assert(false, "Could not retrieve secondary app") }


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

Kotlin+KTX

// 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");

Web

// 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);

Garantiza la creación de informes confiables de Analytics

Google Analytics recopila eventos apenas comienza el flujo de inicio de la aplicación y, en algunas ocasiones, incluso antes de que se haya configurado la instancia de app principal de Firebase. En estos casos, Firebase hace referencia al recurso de Android o a GoogleService-Info.plist en las plataformas de Apple para buscar el ID correcto de la app de Google para almacenar eventos. Por este motivo, te recomendamos que uses los métodos de configuración predeterminados siempre que sea posible.

Si debes configurar el tiempo de ejecución, ten en cuenta los siguientes puntos:

  1. Si utilizas AdMob y solicitas que se muestren anuncios en el inicio como se recomienda, es posible que se omitan algunos datos de Analytics relacionados con anuncios para dispositivos móviles si no usas el enfoque de configuración basado en recursos.
  2. Solo proporciona un ID de la app de Google en cada variante distribuida de tu app. Por ejemplo, si envías la versión 1 de tu app con un GOOGLE_APP_ID determinado en la configuración y, luego, subes la versión 2 con un ID diferente, es posible que se descarten los datos de Analytics.
  3. En las plataformas de Apple, no agregues GoogleService-Info.plist al proyecto si definiste una configuración diferente en el tiempo de ejecución, ya que esto puede generar un cambio aparente de GOOGLE_APP_ID y provocar la pérdida de datos de Analytics.