Ambiente separado de desenvolvimento e produção do Firebase

154

Estou pensando em usar o Firebase como MBaaS, mas não consegui encontrar nenhuma solução confiável para o seguinte problema:

Gostaria de configurar dois ambientes separados do Firebase, um para desenvolvimento e outro para produção, mas não quero fazer uma cópia manual dos recursos (por exemplo, configuração remota, regras de notificação etc.) entre o ambiente de desenvolvimento e produção .

Existe alguma ferramenta ou método em que eu possa confiar? Definir regras de configuração ou notificação remota do zero pode ser uma tarefa assustadora e muito arriscada.

Alguma sugestão? Existe uma abordagem melhor do que ter dois ambientes separados?

Antes de postar outra resposta à pergunta, que explica como configurar contas separadas do Firebase: não é a pergunta, leia-a novamente. A questão é: como TRANSFERIR alterações entre contas de dev e prod separadas ou qualquer solução melhor do que copiar manualmente entre elas.

racs
fonte
3
seria ótimo ter isso como um recurso!
284 Patrick
@Timmerz Veja a primeira resposta: relevante apenas para hospedagem e banco de dados, mas não para outros recursos.
CCR
Eu tive um problema semelhante. Eu o resolvi da seguinte maneira: Verifique isto: stackoverflow.com/questions/51646512/… Resolvi isso da seguinte maneira: 1.crie uma configuração de depuração Siga o link medium.com/@Miqubel/ ... medium.com/@Miqubel/... 2.Then criar um novo banco de dados por favor, siga o link: firebase.google.com/docs/database/usage/... 3.In seu código com base no seu sabor do produto se conectar ao banco de dados correspondente com base sobre o produto
Kunal Khaire
1
@LOG_TAG Qual é o seu motivo para criar uma tag totalmente nova? Isso aborda novas tecnologias ainda não cobertas pelo [firebase]?
Michael Dodd

Respostas:

24

Como todos apontaram - você precisa de mais de um projeto / banco de dados.

Mas, para responder à sua pergunta sobre a necessidade de poder copiar configurações / dados, etc., do desenvolvimento à produção. Eu tinha exatamente a mesma necessidade. Alguns meses de desenvolvimento e teste, eu não queria copiar manualmente os dados.

Meu resultado foi fazer backup dos dados em um balde de armazenamento e restaurá-los a partir daí para o outro banco de dados. É uma maneira bem simples de fazer isso - e eu fiz um backup / restauração de banco de dados inteiro - mas você pode procurar nessa direção por uma maneira mais controlada. Eu não o usei - é muito novo - mas isso pode ser uma solução: Módulo NPM firestore-export-import

Editar : informações sobre backup / exportação / importação do Firestore aqui Cloud Exportando e importando dados do Firestore

Se você estiver usando o Firebase RTDB e não o Firestore - esta documentação pode ajudar: Backups automatizados do Firebase

Você precisará definir as permissões corretamente para permitir que o banco de dados de produção acesse o mesmo depósito de armazenamento que o seu desenvolvimento. Boa sorte.

stevecowling
fonte
1
Obrigado, esta é a melhor resposta até agora.
CCR
4
Para qualquer projeto que tenha alguns milhares de usuários, você acabará movendo alguns dados de um banco de dados de produção para um servidor de temporariedade ou desenvolvimento. É uma pena que isso não esteja embutido no Firebase, mas é algo que precisa ser feito para qualquer tipo de projeto.
Importei o banco de dados usando o guia "Movendo dados entre projetos". Mas ele criou o banco de dados Firestore no modo Datastore. Eu preciso usá-lo no modo nativo.
Debiprasad
54

Se você estiver usando o firebase-tools, existe um comando firebase useque permite configurar qual projeto você está usando parafirebase deploy

firebase use --addtrará uma lista de seus projetos, selecione um e ele solicitará um alias. A partir daí, você pode firebase use aliase firebase deployvai avançar para esse projeto.

No meu uso pessoal, tenho my-app e my-app-dev como projetos no console do Firebase.

Lancheira
fonte
1
Tanto quanto eu entendi, as ferramentas do Firebase são úteis para implantar arquivos e bancos de dados hospedados, mas não fazem nada com o banco de dados, análises ou configuração remota. Ou eu estou esquecendo de alguma coisa?
CCR
@racs parece que isso é recente, mas estou prestes a começar a tentar usar o cli para propagação / manutenção de dados na minha instância de desenvolvimento: firebase.googleblog.com/2015/11/…
Chris
@ Chris obrigado, é um começo, pelo menos. Mas parece uma coisa bastante misteriosa de se fazer. Boa sorte!
CCR
O @racs, no que diz respeito à propagação de dados e fluxo de desenvolvimento, funcionou muito bem. Posso alterar com segurança meu banco de dados de desenvolvimento com base nos comandos npm run com versão e nos dados de semente com versão. Você estava procurando uma maneira de copiar metadados também, mas infelizmente não vi isso.
22716 Chris
@ Chris obrigado por nos informar sobre isso. Esta ainda é uma questão em aberto, até onde posso dizer.
CCR
25

No momento, não estou usando o Firebase, mas considerando-o como você. Parece que o caminho a seguir é criar um projeto completamente separado no console. Havia um post no blog recomendando isso no site antigo do Firebase, mas parece ser removido agora. https://web.archive.org/web/20160310115701/https://www.firebase.com/blog/2015-10-29-managing-development-environments.html

Também esta discussão recomenda o mesmo: https://groups.google.com/forum/#!msg/firebase-talk/L7ajIJoHPcA/7dsNUTDlyRYJ

Patrick
fonte
2
Obrigado pela resposta. Ter dois projetos separados é provavelmente a única opção. No entanto, copiar dados entre eles é complicado, na melhor das hipóteses. Pergunto-me se Firebase Ferramentas poderia copiar regras, configuração público, etc. Parece-me que se trata de apenas operações de banco de dados relacionadas: github.com/firebase/firebase-tools
CCR
2
Não tenho certeza se você já viu isso, mas você pode executar o seu dev contra um firebase-servidor: firebase.googleblog.com/2015/04/...
krico
2
Foi exatamente isso que fiz, mas a pergunta é: como você pode copiar qualquer configuração entre os dois ambientes? Por exemplo. configurações remotas, configuração de audiência, etc? Adicioná-los manualmente ao ambiente de produção é propenso a erros.
CCR
2
Um problema que encontrei é a autenticação com várias instâncias do firebase com o mesmo pacote e assinatura. O console não permitirá que você adicione o mesmo pacote sha1 a mais de um projeto, portanto, isso pode não ser possível. Os documentos dizem que existe uma solução alternativa ao incluir a clientid na lista de permissões, mas eu não tive sucesso com isso. A outra solução é nomes de pacotes separado (mais precisamente 'applicationIds)', mas depois há outras complicações
Patrick
3
Leia também o seguinte: firebase.googleblog.com/2016/08/...
CCR
8

Do jeito que eu fiz:

  1. Eu tinha 2 projetos no firebase - um para DEV outro para PROD
  2. Localmente, meu aplicativo também tinha 2 filiais - uma chamada DEV e a outra PROD
  3. No meu ramo DEV, eu sempre tenho o arquivo JSON do projeto DEV firebase e também o PROD

Dessa forma, não sou obrigado a manter meus JSONs.

Kunal Khaire
fonte
1
Eu entendo, mas não há solução genérica para a pergunta feita de acordo com a versão mais recente do firebase. Você tem que brincar com as opções atuais e obter uma prática recomendada. Pode ser que a minha resposta não foi apontar isso, mas eu só quero ajudar o solicitante com a minha perspectiva.
Kunal Khaire
5

Este post do blog descreve uma abordagem muito simples com um tipo de compilação de depuração e lançamento.

Em poucas palavras:

  • Crie um novo aplicativo no Firebase para cada tipo de construção usando um sufixo de identificação de aplicativo diferente.
  • Configure seu projeto Android com o arquivo JSON mais recente.
  • Usando applicationIdSuffix, altere o ID do aplicativo para corresponder aos diferentes aplicativos no Firebase, dependendo do tipo de compilação.

=> veja o post do blog para uma descrição detalhada.

Se você quiser usar diferentes tipos de build, leia este post extenso no blog oficial do firebase. Ele contém muitas informações valiosas.

Espero que ajude!

Lukas Lechner
fonte
Obrigado pela sua resposta. Consegui configurar aplicativos diferentes, mas ainda estou procurando um método para copiar várias configurações do aplicativo dev FB para o aplicativo prod FB, conforme solicitado na pergunta. (Por exemplo, configuração remota ou configurações de público-alvo).
racs
2
Por favor note que este cria dois aplicativos dentro do mesmo projeto, portanto, irá dividir a alguns serviços, como análise, mas o banco de dados será compartilhado por isso não é uma verdadeira separação de ambientes, como explicado aqui firebase.googleblog.com/2016/08/...
AntPachon
5

Você precisará gerenciar diferentes tipos de compilação

Siga isso

  1. Primeiro, crie um novo projeto no console do Firebase, identifique-se como YOURAPPNAME-DEV

  2. Clique no botão "Adicionar aplicativo Android" e crie um novo aplicativo. Nomeie como com.yourapp.debug, por exemplo. O novo arquivo google-services.json será baixado automaticamente

  3. No diretório src do projeto, crie um novo diretório com o nome "debug" e copie o novo arquivo google-services.json aqui

  4. No nível do módulo build.gradle, adicione este

    debug {
            applicationIdSuffix ".debug"
        }
    

Agora, quando você criar uma depuração, será usado o google-services.json a partir da pasta "debug" e quando você criar o modo de liberação google-services.json a partir do diretório raiz do módulo será considerado.

Chetan
fonte
Caso alguém precise da documentação oficial, o Google Services Gradle Plugin sabe procurar o google-services.json no subdiretório de srcpara o buildType, conforme explicado aqui developers.google.com/android/guides/…
Michael Osofsky
4

Para resolver isso, criei três projetos do Firebase, cada um com o mesmo projeto Android (ou seja, o mesmo applicationIdsem usar o applicationIdSuffixsugerido por outros). Isso resultou em três arquivos google-services.json que eu armazenei no servidor de Integração Contínua (CI) como variáveis ​​de ambiente personalizadas . Para cada estágio da construção (dev / staging / prod), usei o arquivo google-services.json correspondente.

Para o projeto Firebase associado ao dev, em seu projeto Android, adicionei a impressão digital do certificado SHA de depuração. Mas, para preparação e produção, basta que o CI assine o APK.

Aqui está um despojado .gitlab-ci.ymlque funcionou para esta configuração:

# This is a Gitlab Continuous Integration (CI) Pipeline definition
# Environment variables:
#   - variables prefixed CI_ are Gitlab predefined environment variables (https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
#   - variables prefixed GNDR_CI are Gitlab custom environment variables (https://docs.gitlab.com/ee/ci/variables/#creating-a-custom-environment-variable)
#
# We have three Firebase projects (dev, staging, prod) where the same package name is used across all of them but the
# debug signing certificate is only provided for the dev one (later if there are other developers, they can have their
# own Firebase project that's equivalent to the dev one).  The staging and prod Firebase projects use real certificate
# signing so we don't need to enter a Debug signing certificate for them.  We don't check the google-services.json into
# the repository.  Instead it's provided at build time either on the developer's machine or by the Gitlab CI server
# which injects it via custom environment variables.  That way the google-services.json can reside in the default
# location, the projects's app directory.  The .gitlab-ci.yml is configured to copy the dev, staging, and prod equivalents
# of the google-servies.json file into that default location.
#
# References:
# https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html
# /programming/57129588/how-to-setup-firebase-for-multi-stage-release

stages:
  - stg_build_dev
  - stg_build_staging
  - stg_build_prod

jb_build_dev:
  stage: stg_build_dev
  image: jangrewe/gitlab-ci-android
  cache:
    key: ${CI_PROJECT_ID}-android
    paths:
      - .gradle/
  script:
    - cp ${GNDR_CI_GOOGLE_SERVICES_JSON_DEV_FILE} app/google-services.json
    - ./gradlew :app:assembleDebug
  artifacts:
    paths:
      - app/build/outputs/apk/

jb_build_staging:
  stage: stg_build_staging
  image: jangrewe/gitlab-ci-android
  cache:
    key: ${CI_PROJECT_ID}-android
    paths:
      - .gradle/
  dependencies: []
  script:
    - cp ${GNDR_CI_GOOGLE_SERVICES_JSON_STAGING_FILE} app/google-services.json
    - ./gradlew :app:assembleDebug
  artifacts:
    paths:
      - app/build/outputs/apk/

jb_build_prod:
  stage: stg_build_prod
  image: jangrewe/gitlab-ci-android
  cache:
    key: ${CI_PROJECT_ID}-android
    paths:
      - .gradle/
  dependencies: []
  script:
    - cp ${GNDR_CI_GOOGLE_SERVICES_JSON_PROD_FILE} app/google-services.json

    # GNDR_CI_KEYSTORE_FILE_BASE64_ENCODED created on Mac via:
    # base64 --input ~/Desktop/gendr.keystore --output ~/Desktop/keystore_base64_encoded.txt
    # Then the contents of keystore_base64_encoded.txt were copied and pasted as a Gitlab custom environment variable
    # For more info see http://android.jlelse.eu/android-gitlab-ci-cd-sign-deploy-3ad66a8f24bf
    - cat ${GNDR_CI_KEYSTORE_FILE_BASE64_ENCODED} | base64 --decode > gendr.keystore

    - ./gradlew :app:assembleRelease
      -Pandroid.injected.signing.store.file=$(pwd)/gendr.keystore
      -Pandroid.injected.signing.store.password=${GNDR_CI_KEYSTORE_PASSWORD}
      -Pandroid.injected.signing.key.alias=${GNDR_CI_KEY_ALIAS}
      -Pandroid.injected.signing.key.password=${GNDR_CI_KEY_PASSWORD}
  artifacts:
    paths:
      - app/build/outputs/apk/

Estou feliz com esta solução porque ela não se baseia nos truques de build.gradle que, acredito, são muito opacos e, portanto, difíceis de manter. Por exemplo, quando tentei as abordagens usando s applicationIdSuffixdiferentes buildType, descobri que não conseguia executar testes instrumentados nem mesmo compilar quando tentei alternar tipos de compilação usando testBuildType. O Android parecia dar propriedades especiais às debug buildTypequais eu não conseguia inspecionar para entender.

Virtualmente, os scripts de CI são bastante transparentes e fáceis de manter, na minha experiência. De fato, a abordagem que descrevi funcionou: quando executei cada um dos APKs gerados pelo CI em um emulador, a etapa "Execute seu aplicativo para verificar a instalação" do console do Firebase passou de

Verificando se o aplicativo se comunicou com nossos servidores. Pode ser necessário desinstalar e reinstalar o aplicativo.

para:

Parabéns, você adicionou o Firebase com sucesso ao seu aplicativo!

para todos os três aplicativos, como eu os iniciei um a um em um emulador.

Michael Osofsky
fonte
Obrigado por toda essa descrição detalhada, Michael. Eu gerenciei o mesmo resultado simplesmente adicionando sabores separados e copiando o google-services.json apropriado nas pastas de cada sabor. No entanto, essa não foi minha pergunta, leia-a novamente.
CCR
Concordo @racs mas infelizmente quando eu escrevi stackoverflow.com/questions/37450439/... , foi marcado como um duplicado da sua pergunta por stackoverflow.com/users/807126/doug-stevenson
Michael Osofsky
1
Doug ... O que você fez! : Não importa sua resposta aqui, tenho certeza de que é útil para algumas pessoas que buscam uma solução para o ambiente separado.
CCR
Sim, procuramos uma solução para nosso aplicativo móvel que precisa de ambientes separados com o serviço Firebase. Este é definitivamente um bom ponto de partida para nós. Vamos tentar.
LT
2

O Firebase possui uma página que explica como configurá-lo para dev e prod

https://firebase.google.com/docs/functions/config-env

Definir configuração do ambiente para seu projeto Para armazenar dados do ambiente, você pode usar as funções do firebase: config: set command na CLI do Firebase. Cada chave pode ser espaçada por nomes usando pontos para agrupar a configuração relacionada. Lembre-se de que apenas caracteres minúsculos são aceitos nas chaves; caracteres maiúsculos não são permitidos.

Por exemplo, para armazenar a ID do cliente e a chave da API em "Some Service", você pode executar:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

Recuperar a configuração atual do ambiente Para inspecionar o que está atualmente armazenado na configuração do ambiente para seu projeto, você pode usar as funções do firebase: config: get. Ele produzirá JSON algo como isto:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}
Derek Dawson
fonte
1
Resolve para um 404. Da próxima vez, inclua também o conteúdo!
CorayThan
1

Estou atualizando esta resposta com base nas informações que acabei de encontrar.

Passo 1

No firebase.google.com, crie seus vários ambientes (por exemplo, dev, staging, prod)


mysite-dev

mysite-staging

mysite-prod


Passo 2

uma. Vá para o diretamente que você deseja que seja o padrão (por exemplo, dev)

b. Correfirebase deploy

c. Depois de implantado, executefirebase use --add

d. Uma opção será exibida para selecionar os diferentes projetos que você possui atualmente.

Role até o projeto que você deseja adicionar: teste do meu site e selecione-o.

e Você será solicitado a fornecer um alias para esse projeto. Digite o teste .

Execute os itens ae novamente para prod e dev, para que cada ambiente tenha um alias


Saiba em que ambiente você está

Corre firebase use default (mysite-dev)

* dev (mysite-dev)

staging (mysite-staging)

prod (mysite-dev)

(um dos ambientes terá um asterisco à esquerda. Esse é o local em que você está atualmente. Também será destacado em azul)


Alternar entre ambientes

Corra firebase use stagingou firebase use prodpara se mover entre eles.

Quando estiver no ambiente desejado, execute firebase deploye seu projeto será implantado lá.

Aqui estão alguns links úteis ...

Referência da CLI

Implementando em vários ambientes

Espero que isto ajude.

Jared Newnam
fonte
Quando você diz vários ambientes, quer dizer vários projetos?
walidvb
Quero dizer vários ambientes. Leia o post aqui para esclarecimentos. É assim que se chama. Tem a ver com o mesmo projeto, mas em dev / qa e produção.
Jared Newnam
Obrigado, acabei de assistir o vídeo na íntegra. Dito isto, entendo que ele usa projetos diferentes para os diferentes ambientes, não um ambiente dedicado dentro do mesmo projeto
walidvb
0

A maneira como fazemos isso é criando diferentes arquivos de chave json para diferentes ambientes. Usamos o recurso de conta de serviço conforme recomendado pelo Google e temos um arquivo de desenvolvimento e outro para produção

insira a descrição da imagem aqui

vsingh
fonte
0

Crie o projeto Tow com o Dev e o Production Environment na base do firebase Faça o download do arquivo json em thre

e configure o SDK conforme: https://firebase.google.com/docs/android/setup Ou para o Crashlytics: https://firebase.google.com/docs/crashlytics/get-started?platform=android

Primeiro, coloque o respectivo google_services.json para cada buildType nos seguintes locais:

app/src/debug/google_services.json
app/src/test/google_services.json
app/google_services.json

Nota: Aplicativo raiz / google_services.json Esse arquivo deve estar lá de acordo com as variantes de construção, copie o código json no arquivo json raiz

Agora, vamos preparar algumas tarefas gradle no build.gradle do seu aplicativo: para automatizar a movimentação do google_services.json apropriado para app / google_services.json

copie isso no arquivo app / Gradle

task switchToDebug(type: Copy) {
description = 'Switches to DEBUG google-services.json'
from "src/debug"
include "google-services.json"
into "."
}

task switchToRelease(type: Copy) {
description = 'Switches to RELEASE google-services.json'
from "src/release"
include "google-services.json"
into "."
}

Ótimo - mas ter que executar manualmente essas tarefas antes de criar seu aplicativo é complicado. Queremos que a tarefa de cópia apropriada acima seja executada algum tempo antes: assembleDebug ou: assembleRelease for executado. Vamos ver o que acontece quando: assembleRelease é executado: copie este no arquivo / gradlew

Zaks-MBP:my_awesome_application zak$ ./gradlew assembleRelease
Parallel execution is an incubating feature.
.... (other tasks)
:app:processReleaseGoogleServices
....
:app:assembleRelease

Observe a tarefa: app: processReleaseGoogleServices. Esta tarefa é responsável pelo processamento do arquivo raiz google_services.json. Queremos que o google_services.json correto seja processado, portanto, devemos executar nossa tarefa de cópia imediatamente antes. Adicione isso ao seu build.gradle. Observe o anexo afterEvaluate.

copie isso no arquivo app / Gradle

afterEvaluate {
processDebugGoogleServices.dependsOn switchToDebug
processReleaseGoogleServices.dependsOn switchToRelease
}

Agora, a qualquer momento: app: processReleaseGoogleServices é chamado, nosso recém-definido: app: switchToRelease será chamado com antecedência. A mesma lógica para o debug buildType. Você pode executar: app: assembleRelease e a versão de lançamento google_services.json serão automaticamente copiados para a pasta raiz do seu módulo de aplicativo.

Shaikh Mohib
fonte
1
Você colocou muita energia nessa resposta, mas 1. isso não tem nada a ver com a pergunta (leia-a novamente), 2. você não precisa copiar o google-services.jsonarquivo para a pasta raiz, se o mantiver em a pasta de sabor que está perfeitamente bem. Em vez disso, assembleReleasevocê pode simplesmente invocar uma assembleTestReleasetarefa.
CCR