Configurar vários projetos

Esta página descreve como usar mais de um projeto do Firebase em seu app.

Muitos apps precisam apenas de um único projeto do Firebase e da configuração padrão descrita nos guias Primeiras etapas. Exemplos de quando pode ser útil usar vários projetos do Firebase incluem:

  • configurar seu ambiente de desenvolvimento para usar projetos do Firebase diferentes com base no tipo de build ou no destino;
  • acessar o conteúdo de vários projetos do Firebase no seu app.

Suporte a ambientes diferentes

Um caso de uso comum é oferecer suporte a projetos separados do Firebase nos seus ambientes de desenvolvimento e produção.

Os SDKs da Web e Admin são configurados ao transmitir diretamente os valores para as funções de inicialização deles. Para esse SDK, use uma verificação de tempo de execução para selecionar variáveis de configuração de desenvolvimento ou de produção.

As plataformas Android e Apple (e os respectivos wrappers Unity e C++) normalmente carregam a configuração de um arquivo de configuração: GoogleService-Info.plist na plataforma Apple e google-services.json no Android. Esses arquivos são lidos em um objeto de opções (FIROption ou FirebaseOptions) que é referenciado pelo objeto do aplicativo do Firebase (FIRApp ou FirebaseApp).

Para essas plataformas, trocar de ambiente é geralmente uma decisão feita no tempo de build usando arquivos de configuração diferentes para cada ambiente.

Suporte a vários ambientes no aplicativo para Apple

Por padrão, FirebaseApp.configure() carrega o arquivo GoogleService-Info.plist junto do aplicativo. Caso seus ambientes de desenvolvimento e de produção estejam configurados como destinos separados no Xcode, é possível:

  • fazer o download dos dois arquivos GoogleService-Info.plist;
  • armazenar os dois arquivos em diretórios diferentes;
  • adicionar ambos ao seu projeto do Xcode;
  • associar os arquivos distintos a destinos diferentes usando o painel "Associação de destino":

Painel "Associação de destino"

Se os builds são parte de um único destino, a melhor opção é dar nomes exclusivos aos dois arquivos de configuração (por exemplo, GoogleService-Info-Free.plist e GoogleService-Info-Paid.plist). Em seguida, escolha qual plist carregar no ambiente de execução. Isso é mostrado neste exemplo:

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

Suporte a vários ambientes no app Android

No Android, o arquivo google-services.json é processado em recursos de string Android pelo plug-in do Gradle do Google Services. Veja os recursos que são criados em Como processar o arquivo JSON na documentação do plug-in do Google Services.

É possível ter vários arquivos google-services.json para diferentes variantes de build. Basta colocar os arquivos google-services.json em diretórios dedicados que foram nomeados para cada variante na raiz do módulo do app. Por exemplo, se você tiver as variantes "development" e "release" no build, sua configuração pode ser organizada da seguinte maneira:

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

Para saber mais, consulte Como adicionar o arquivo JSON na documentação do plug-in do Google Services.

Esses recursos são carregados pelo FirebaseInitProvider que é executado antes do código do seu aplicativo e inicializa as APIs do Firebase usando esses valores.

Como esse provedor somente lê os recursos com nomes conhecidos, outra opção é adicionar os recursos de string diretamente ao seu app em vez de usar o plug-in Gradle do Google Services. Para isso, você pode:

  • remover google-services plug-in da sua raiz build.gradle;
  • excluir google-services.json do seu projeto;
  • adicionar os recursos de string diretamente;
  • excluir apply plugin: 'com.google.gms.google-services' do seu aplicativo build.gradle.

Usar vários projetos no aplicativo

Às vezes, é necessário acessar projetos diferentes usando a mesma API, por exemplo, ao acessar várias instâncias do banco de dados. Na maioria dos casos, há um objeto central do Firebase que gerencia a configuração de todas as APIs do Firebase. Esse objeto é inicializado como parte da configuração normal. No entanto, quando você quiser acessar vários projetos em um único aplicativo, precisará de um objeto diferente de aplicativo do Firebase para se referir a cada app individualmente. Você decide como inicializar essas outras instâncias.

Em ambos os casos, primeiro é necessário criar um objeto de opções do Firebase para guardar os dados de configuração do aplicativo do Firebase. A documentação completa das opções está disponível na documentação de referência da API para as classes a seguir:

O uso dessas classes para dar suporte a vários projetos em um aplicativo é mostrado nestes exemplos:

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

Depois de inicializar esse objeto de opções, use-o para configurar uma instância adicional do aplicativo do Firebase. Em todos os exemplos mostrados abaixo usamos a string secondary. Esse nome é usado para recuperar a instância do app e para diferenciá-la de outras instâncias, incluindo a instância padrão (chamada [PADRÃO]). Escolha uma string adequada para o uso pretendido do outro projeto do Firebase.

Os snippets a seguir mostram a conexão a um banco de dados alternativo do Realtime Database. As APIs de outros recursos do Firebase seguem o mesmo padrão.

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

Garanta relatórios confiáveis para Analytics

O Google Analytics coleta eventos bem no início do fluxo de inicialização do app, em algumas ocasiões antes da principal instância do app do Firebase ter sido configurada. Nesses casos, o Firebase faz referência ao recurso Android ou ao GoogleService-Info.plist nas plataformas Apple para procurar o ID do Google app correto onde armazenar eventos. Por esse motivo, recomendamos usar os métodos de configuração padrão sempre que possível.

Se a configuração de tempo de execução for necessária, observe as seguintes ressalvas:

  1. Se você estiver usando a AdMob e solicitar anúncios na inicialização conforme recomendado, poderá perder alguns dados do Analytics relacionados aos anúncios para dispositivos móveis quando não estiver usando a abordagem de configuração baseada em recursos.
  2. Forneça um único ID do Google app em cada variante distribuída do seu aplicativo. Por exemplo, se você enviar a versão 1 do app com um determinado GOOGLE_APP_ID na configuração e depois fizer upload da versão 2 com um ID diferente, isso causará o descarte dos dados de análise.
  3. Na plataforma Apple, não adicione GoogleService-Info.plist ao projeto se você fornecer configurações diferentes no ambiente de execução, já que isso pode resultar em uma mudança aparente do GOOGLE_APP_ID e causar perdas no Analytics.