Entorno independiente de desarrollo y producción de Firebase


154

Estoy considerando usar Firebase como MBaaS, sin embargo, no pude encontrar ninguna solución confiable para el siguiente problema:

Me gustaría configurar dos entornos Firebase separados, uno para el desarrollo y otro para la producción, pero no quiero hacer una copia manual de las características (por ejemplo, configuración de configuración remota, reglas de notificación, etc.) entre el entorno de desarrollo y producción .

¿Hay alguna herramienta o método en el que pueda confiar? Configurar la configuración remota o las reglas de notificación desde cero puede ser una tarea desalentadora y demasiado arriesgada.

¿Alguna sugerencia? ¿Existe un mejor enfoque que tener dos entornos separados?

Antes de publicar otra respuesta a la pregunta que explica cómo configurar cuentas separadas de Firebase: no es la pregunta, léala nuevamente. La pregunta es: cómo TRANSFERIR cambios entre cuentas de desarrollo y producción separadas o cualquier solución mejor que copiar manualmente entre ellas.


3
¡sería genial tener esto como una característica!
Patrick


@Timmerz Consulte la primera respuesta: solo es relevante para el alojamiento y la base de datos, pero no para otras funciones.
racs

Tuve un problema similar. Lo resolví de la siguiente manera: Verifique esto: stackoverflow.com/questions/51646512/… Resolví esto de la siguiente manera: 1.Cree una configuración de depuración Siga el enlace medium.com/@Miqubel/ … Medium.com/@Miqubel/… 2. Luego cree una nueva base de datos Siga el enlace: firebase.google.com/docs/database/usage/… 3.En su código basado en el sabor de su producto, conéctese a la base de datos correspondiente en el producto
Kunal Khaire

1
@LOG_TAG ¿Cuál es su razonamiento para crear una etiqueta completamente nueva? ¿Aborda esto alguna tecnología nueva que no esté cubierta por [firebase]?
Michael Dodd

Respuestas:


24

Como todos han señalado, necesita más de un proyecto / base de datos.

Pero para responder a su pregunta sobre la necesidad de poder copiar configuraciones / datos, etc. desde el desarrollo hasta la producción. Tenía exactamente la misma necesidad. Unos meses en desarrollo y pruebas, no quería copiar manualmente los datos.

Mi resultado fue hacer una copia de seguridad de los datos en un depósito de almacenamiento y luego restaurarlos desde allí en la otra base de datos. Es una forma bastante cruda de hacerlo, e hice una copia de seguridad / restauración de la base de datos completa, pero es posible que pueda buscar en esa dirección una forma más controlada. No lo he usado, es muy nuevo, pero esta podría ser una solución: Módulo NPM firestore-export-import

Editar : información de copia de seguridad / exportación / importación de Firestore aquí Cloud Firestore Exportación e importación de datos

Si está utilizando Firebase RTDB, y no Firestore, esta documentación podría ayudar: Firebase Automated Backups

Deberá establecer los permisos correctamente para permitir que su base de datos de producción acceda al mismo depósito de almacenamiento que su desarrollo. Buena suerte.


1
Gracias, esta es la mejor respuesta hasta ahora.
racs

44
Para cualquier proyecto que tenga unos pocos miles de usuarios, terminará moviendo algunos datos de una base de datos de producción a un servidor de preparación o desarrollo. Es una pena que esto no esté integrado en Firebase, pero es algo que debería hacerse para cualquier tipo de proyecto.

Importé la base de datos utilizando la guía "Mover datos entre proyectos". Pero creó la base de datos de Firestore en modo Datastore. Necesito usarlo en modo nativo.
Debiprasad

54

Si está utilizando firebase-tools, hay un comando firebase useque le permite configurar para qué proyecto está utilizandofirebase deploy

firebase use --addAparecerá una lista de sus proyectos, seleccione uno y le pedirá un alias. A partir de ahí, puede firebase use aliasy firebase deployempujará a ese proyecto.

En mi uso personal, tengo my-app y my-app-dev como proyectos en la consola de Firebase.


1
Según tengo entendido, las herramientas de Firebase son útiles para implementar archivos alojados y bases de datos, pero no hacen nada con la base de datos, análisis o configuración remota. ¿O me estoy perdiendo algo?
racs

@racs parece que esto es reciente, pero estoy a punto de comenzar a intentar usar el cli para la siembra de datos / mantenimiento de datos en mi instancia de desarrollo: firebase.googleblog.com/2015/11/…
Chris

@ Chris gracias, al menos es un comienzo. Pero parece algo arcano que hacer. ¡Buena suerte!
racs

@racs en lo que respecta a la siembra de datos y el flujo de desarrollo, funcionó muy bien. Puedo mutar de manera confiable mi base de datos de desarrollo en base a comandos de ejecución npm versionados y datos semilla versionados. También estaba buscando una forma de copiar metadatos, pero desafortunadamente no la he visto.
Chris

@ Chris gracias por informarnos al respecto. Esta sigue siendo una pregunta abierta por lo que puedo decir.
racs

25

Actualmente no estoy usando Firebase, pero lo considero como tú. Parece que el camino a seguir es crear un proyecto completamente separado en la consola. Hubo una publicación de blog recomendando esto en el antiguo sitio de Firebase, aunque parece que ahora se eliminará. https://web.archive.org/web/20160310115701/https://www.firebase.com/blog/2015-10-29-managing-development-environments.html

También esta discusión recomienda lo mismo: https://groups.google.com/forum/#!msg/firebase-talk/L7ajIJoHPcA/7dsNUTDlyRYJ


2
Gracias por la respuesta. Lo más probable es que tener dos proyectos separados sea la única opción. Sin embargo, copiar datos entre ellos es complicado en el mejor de los casos. Me pregunto si Firebase Tools podría copiar reglas, configuración de audiencia, etc. Me parece que solo se trata de operaciones relacionadas con la base de datos: github.com/firebase/firebase-tools
racs

2
No estoy seguro si ha visto esto, pero puede ejecutar su desarrollador contra un servidor firebase
krico

2
Eso es exactamente lo que he hecho, pero la pregunta es: ¿cómo puede copiar cualquier configuración entre los dos entornos? P.ej. configuraciones remotas, configuración de audiencia, etc. Agregarlos manualmente al entorno de producción es bastante propenso a errores.
racs

2
Un problema con el que me he encontrado es la autenticación con varias instancias de Firebase con el mismo paquete y firma. La consola no le permitirá agregar el mismo paquete sha1 a más de un proyecto, por lo que esto puede no ser posible. Los documentos dicen que hay una solución al incluir en la lista blanca clientid, pero no he tenido éxito con eso. La otra solución es los nombres de paquetes separados (más exactamente 'ID de aplicación)' pero luego hay otras complicaciones
Patrick


8

La forma en que lo hice:

  1. Tenía 2 proyectos en firebase, uno para DEV y otro para PROD
  2. A nivel local, mi aplicación también tenía 2 sucursales: una llamada DEV, la otra llamada PROD
  3. En mi rama DEV siempre tengo un archivo JSON del proyecto DEV firebase y también para PROD

De esta manera, no estoy obligado a mantener mis JSON.


1
Entiendo, pero no hay una solución genérica a la pregunta formulada según la última versión de Firebase. Tienes que jugar con las opciones actuales y derivar una mejor práctica. Puede ser que mi respuesta no fue señalar esto, pero solo quiero ayudar al que pregunta con mi perspectiva.
Kunal Khaire

5

Esta publicación de blog describe un enfoque muy simple con un tipo de compilación de depuración y lanzamiento.

En una palabra:

  • Cree una nueva aplicación en Firebase para cada tipo de compilación utilizando un sufijo de ID de aplicación diferente.
  • Configure su proyecto de Android con el último archivo JSON.
  • Usando applicationIdSuffix, cambie el Id. De la aplicación para que coincida con las diferentes aplicaciones en Firebase según el tipo de compilación.

=> vea el blog para una descripción detallada.

Si desea utilizar diferentes sabores de construcción, lea esta extensa entrada de blog desde el blog oficial de base de fuego. Contiene mucha información valiosa.

¡Espero que ayude!


Gracias por su respuesta. Pude configurar diferentes aplicaciones, pero todavía estoy buscando un método para copiar varias configuraciones de la aplicación FB dev a la aplicación FB prod como pedí en la pregunta. (Por ejemplo, configuración remota o configuración de audiencia.)
racs

2
Tenga en cuenta que esto crea dos aplicaciones dentro del mismo proyecto, por lo tanto, separará algunos servicios, como análisis, pero la base de datos se compartirá, por lo que no es una separación real de los entornos, como se explica aquí firebase.googleblog.com/2016/08/…
AntPachon

5

Deberá administrar diferentes tipos de compilación

Sigue esto

  1. Primero, cree un nuevo proyecto en la consola de Firebase, nombre id como YOURAPPNAME-DEV

  2. Haga clic en el botón "Agregar aplicación de Android" y cree una nueva aplicación. Llámalo com.yourapp.debug, por ejemplo. El nuevo archivo google-services.json se descargará automáticamente

  3. En el directorio src de su proyecto, cree un nuevo directorio con el nombre "debug" y copie el nuevo archivo google-services.json aquí

  4. En su nivel de módulo build.gradle agregue esto

    debug {
            applicationIdSuffix ".debug"
        }
    

Ahora, cuando construya una depuración, se utilizará google-services.json desde la carpeta "debug" y cuando construya en modo de lanzamiento se considerará google-services.json desde el directorio raíz del módulo.


En caso de que alguien necesite la documentación oficial, Google Services Gradle Plugin sabe buscar google-services.json en el subdirectorio de srcbuildType como se explica aquí developers.google.com/android/guides/…
Michael Osofsky

4

Para resolver esto para mi situación, creé tres proyectos de Firebase, cada uno con el mismo proyecto de Android (es decir, el mismo applicationIdsin usar el applicationIdSuffixsugerido por otros). Esto dio como resultado tres archivos google-services.json que almacené en mi servidor de Integración Continua (CI) como variables de entorno personalizadas . Para cada etapa de la compilación (dev / staging / prod), utilicé el archivo google-services.json correspondiente.

Para el proyecto Firebase asociado con dev, en su proyecto de Android, agregué la huella digital del certificado SHA de depuración. Pero para la puesta en escena y la producción, solo tengo que CI firme el APK.

Aquí hay un despojado .gitlab-ci.ymlque funcionó para esta configuración:

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

Estoy contento con esta solución porque no se basa en trucos build.gradle que creo que son demasiado opacos y, por lo tanto, difíciles de mantener. Por ejemplo, cuando probé los enfoques usando applicationIdSuffixy diferentes buildTypes, descubrí que no podía ejecutar pruebas instrumentadas o incluso compilar cuando intentaba cambiar los tipos de compilación usando testBuildType. Android parecía dar propiedades especiales a las debug buildTypeque no pude inspeccionar para entender.

Virtualmente, los scripts de CI son bastante transparentes y fáciles de mantener, en mi experiencia. De hecho, el enfoque que describí funcionó: cuando ejecuté cada uno de los APK generados por CI en un emulador, el paso "Ejecutar su aplicación para verificar la instalación" de la consola Firebase pasó de

Comprobando si la aplicación se ha comunicado con nuestros servidores. Es posible que deba desinstalar y reinstalar su aplicación.

a:

¡Felicitaciones, has agregado con éxito Firebase a tu aplicación!

para las tres aplicaciones cuando las comencé una por una en un emulador.


Gracias por toda esta descripción detallada, Michael. Logré el mismo resultado simplemente agregando sabores separados y copiando el apropiado google-services.json debajo de las carpetas para cada sabor. Sin embargo, esta no era mi pregunta, por favor léala nuevamente.
racs

Estoy de acuerdo @racs pero desafortunadamente cuando escribí stackoverflow.com/questions/37450439/... , que fue marcado como un duplicado de su pregunta por stackoverflow.com/users/807126/doug-stevenson
Michael Osofsky

1
Doug ... ¿Qué has hecho? : DI no me importa su respuesta aquí, estoy seguro de que es útil para algunas personas que buscan una solución para un entorno separado.
racs

Sí, hemos estado buscando una solución para nuestra aplicación móvil que necesita entornos separados con el servicio Firebase. Este es definitivamente un buen punto de partida para nosotros. Lo intentaremos
LT

2

Firebase tiene una página sobre esto que explica cómo configurarlo para desarrolladores y productos.

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

Establecer la configuración del entorno para su proyecto Para almacenar datos del entorno, puede usar las funciones de firebase: config: comando set en la CLI de Firebase. Cada clave puede tener un espacio de nombres usando períodos para agrupar la configuración relacionada. Tenga en cuenta que solo se aceptan caracteres en minúsculas en las claves; No se permiten caracteres en mayúscula.

Por ejemplo, para almacenar el ID de cliente y la clave API para "Some Service", puede ejecutar:

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

Recuperar la configuración actual del entorno Para inspeccionar lo que está almacenado actualmente en la configuración del entorno para su proyecto, puede usar las funciones de firebase: config: get. Producirá JSON algo como esto:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

1
Resuelve un 404. ¡La próxima vez incluye también el contenido!
CorayThan

1

Estoy actualizando esta respuesta según la información que acabo de encontrar.

Paso 1

En firebase.google.com, cree sus múltiples entornos (es decir, dev, puesta en escena, prod)


mysite-dev

puesta en escena de mysite

mysite-prod


Paso 2

a. Mover al directamente que desea ser su predeterminado (es decir, dev)

si. correrfirebase deploy

C. Una vez desplegado, ejecutefirebase use --add

re. Aparecerá una opción para seleccionar entre los diferentes proyectos que tiene actualmente.

Desplácese hasta el proyecto que desea agregar: mysite-staging y selecciónelo.

mi. Luego se le pedirá un alias para ese proyecto. Entra en escena .

Ejecute los elementos ae nuevamente para prod y dev, de modo que cada entorno tenga un alias


Sepa en qué entorno se encuentra

correr firebase use default (mysite-dev)

* dev (mysite-dev)

staging (mysite-staging)

prod (mysite-dev)

(uno de los entornos tendrá un asterisco a la izquierda. Ese es el que se encuentra actualmente. También se resaltará en azul)


Cambiar entre entornos

Correr firebase use stagingo firebase use prodmoverse entre ellos.

Una vez que esté en el entorno que desea, ejecute firebase deployy su proyecto se implementará allí.

Aquí hay un par de enlaces útiles ...

Referencia de CLI

Implementación en múltiples entornos.

Espero que esto ayude.


Cuando dices entornos múltiples, ¿te refieres a proyectos múltiples?
walidvb

Me refiero a múltiples ambientes. Lea la publicación aquí para aclaraciones. Así se titula. Tiene que ver con el mismo proyecto pero en dev / qa y producción.
Jared Newnam hace

Gracias, acabo de ver el video en su totalidad. Dicho esto, entiendo que usa diferentes proyectos para los diferentes entornos, no un entorno dedicado dentro del mismo proyecto
walidvb

0

La forma en que lo estamos haciendo es creando diferentes archivos json key para diferentes entornos. Hemos utilizado la función de cuenta de servicio recomendada por Google y tenemos un archivo de desarrollo y otro para producción

ingrese la descripción de la imagen aquí


0

Cree el proyecto Tow con Dev y Production Environment en firebase Descargue el archivo json de tres

y configure el SDK según: https://firebase.google.com/docs/android/setup O para Crashlytics: https://firebase.google.com/docs/crashlytics/get-started?platform=android

Primero, coloque los respectivos google_services.json para cada buildType en las siguientes ubicaciones:

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

Nota: Aplicación raíz / google_services.json Este archivo debe estar allí de acuerdo con las variantes de compilación, copie el código json en el archivo json raíz

Ahora, agilicemos algunas tareas de gradle en su: build.gradle de la aplicación para automatizar el movimiento de google_services.json a app / google_services.json

copia esto en la aplicación / archivo 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 "."
}

Genial, pero tener que ejecutar manualmente estas tareas antes de crear su aplicación es engorroso. Queremos que la tarea de copia adecuada anterior se ejecute en algún momento antes: assembleDebug o: assembleRelease se ejecuta. Veamos qué sucede cuando: assembleRelease se ejecuta: copie este en el archivo / gradlew

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

Observe la tarea: app: processReleaseGoogleServices. Esta tarea es responsable de procesar el archivo raíz google_services.json. Queremos que se procese el google_services.json correcto, por lo que debemos ejecutar nuestra tarea de copia inmediatamente antes. Agregue esto a su build.gradle. Tenga en cuenta el cierre afterEvaluate.

copia esto en la aplicación / archivo Gradle

afterEvaluate {
processDebugGoogleServices.dependsOn switchToDebug
processReleaseGoogleServices.dependsOn switchToRelease
}

Ahora, en cualquier momento: se llama a app: processReleaseGoogleServices, se llamará a nuestra recién definida: app: switchToRelease de antemano. Misma lógica para el debug buildType. Puede ejecutar: app: assembleRelease y la versión de lanzamiento google_services.json se copiará automáticamente en la carpeta raíz del módulo de la aplicación.


1
Puso mucha energía en esta respuesta, pero 1. esto no tiene nada que ver con la pregunta (léala de nuevo), 2. no tiene que copiar el google-services.jsonarchivo a la carpeta raíz, si la guarda en la carpeta de sabores que está perfectamente bien. En cambio assembleRelease, puede invocar una assembleTestReleasetarea.
racs
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.