Oddzielne środowisko deweloperskie i produkcyjne Firebase

154

Rozważam użycie Firebase jako MBaaS, jednak nie mogłem znaleźć niezawodnego rozwiązania następującego problemu:

Chciałbym skonfigurować dwa oddzielne środowiska Firebase, jedno do programowania, a drugie do produkcji, ale nie chcę ręcznie kopiować funkcji (np. Zdalnej konfiguracji konfiguracji, reguł powiadomień itp.) Między środowiskiem deweloperskim a produkcyjnym .

Czy jest jakieś narzędzie lub metoda, na której mogę polegać? Konfigurowanie zdalnej konfiguracji lub reguł powiadomień od podstaw może być trudnym zadaniem i zbyt ryzykownym.

Jakieś sugestie? Czy jest lepsze podejście niż posiadanie dwóch oddzielnych środowisk?

Zanim opublikujesz kolejną odpowiedź na pytanie, które wyjaśnia, jak skonfigurować oddzielne konta Firebase: to nie jest pytanie, przeczytaj je ponownie. Pytanie brzmi: jak PRZENOSIĆ zmiany między oddzielnymi kontami deweloperskimi i prod lub jakiekolwiek lepsze rozwiązanie niż ręczne kopiowanie między nimi.

racs
źródło
3
byłoby wspaniale mieć to jako funkcję!
Patrick
@Timmerz Zobacz pierwszą odpowiedź: dotyczy tylko hostingu i bazy danych, ale nie innych funkcji.
wyścigi
Miałem podobny problem, rozwiązałem go w następujący sposób: Sprawdź to: stackoverflow.com/questions/51646512/ ... Rozwiązałem to w następujący sposób: 1. utwórz konfigurację debugowania Proszę skorzystać z linku medium.com/@Miqubel/ ... medium.com/@Miqubel/... 2.Then utworzyć nową bazę danych, proszę skorzystać z linku: firebase.google.com/docs/database/usage/... 3.W kodu opartego na smak produktu podłączyć do odpowiedniej bazy danych w oparciu produkt
Kunal Khaire
1
@LOG_TAG Jaki jest Twój powód, dla którego tworzysz zupełnie nowy tag? Czy dotyczy to nowych technologii, które nie są jeszcze objęte [firebase]?
Michael Dodd

Odpowiedzi:

24

Jak wszyscy zauważyli - potrzebujesz więcej niż jednego projektu / bazy danych.

Ale żeby odpowiedzieć na twoje pytanie dotyczące potrzeby kopiowania ustawień / danych itp. Z rozwoju do produkcji. Miałem dokładnie taką samą potrzebę. Po kilku miesiącach programowania i testowania nie chciałem ręcznie kopiować danych.

Rezultatem było utworzenie kopii zapasowej danych w zasobniku pamięci, a następnie przywrócenie ich stamtąd do innej bazy danych. Jest to dość prymitywny sposób - i zrobiłem kopię zapasową / przywrócenie całej bazy danych - ale możesz spojrzeć w tym kierunku, aby uzyskać bardziej kontrolowany sposób. Nie używałem go - jest bardzo nowy - ale może to być rozwiązanie: Moduł NPM firestore-export-import

Edycja : tutaj kopia zapasowa / eksport / import Firestore Cloud Firestore Eksportowanie i importowanie danych

Jeśli używasz Firebase RTDB, a nie Firestore - ta dokumentacja może pomóc: Automatyczne kopie zapasowe Firebase

Będziesz musiał poprawnie ustawić uprawnienia, aby umożliwić Twojej produkcyjnej bazie danych dostęp do tego samego zasobnika pamięci, co program. Powodzenia.

stevecowling
źródło
1
Dzięki, to jak dotąd najlepsza odpowiedź.
wyścigi
4
W przypadku każdego projektu, który ma kilka tysięcy użytkowników, w końcu przeniesiesz niektóre dane z produkcyjnej bazy danych na serwer pomostowy lub programistyczny. Szkoda, że ​​nie jest to wbudowane w Firebase, ale jest to coś, co należałoby zrobić dla każdego rodzaju projektu.
Zaimportowałem bazę danych korzystając z poradnika „Przenoszenie danych między projektami”. Ale utworzył bazę danych Firestore w trybie Datastore. Muszę go używać w trybie natywnym.
Debiprasad
54

Jeśli używasz narzędzi firebase, istnieje polecenie, firebase usektóre pozwala ustawić projekt, którego używaszfirebase deploy

firebase use --addwyświetli listę twoich projektów, wybierz jeden i zapyta cię o alias. Stamtąd możesz firebase use aliasi firebase deploybędziesz naciskać na ten projekt.

Do użytku osobistego mam projekty my-app i my-app-dev jako projekty w konsoli Firebase.

Pudełko śniadaniowe
źródło
1
O ile rozumiem, narzędzia Firebase są przydatne do wdrażania hostowanych plików i bazy danych, ale nie robią nic z bazą danych, analityką ani zdalną konfiguracją. A może coś mi brakuje?
wyścigi
@racs, wygląda na to, że to niedawno, ale mam zamiar zacząć używać cli do wysyłania / zarządzania danymi na mojej instancji deweloperskiej
Chris
@chris thanks, to przynajmniej początek. Ale wygląda to na dość tajemniczą rzecz. Powodzenia!
wyścigi
@racs, jeśli chodzi o rozsiewanie danych i przepływ rozwoju, wyszło naprawdę dobrze. Mogę niezawodnie mutować moją deweloperską bazę danych na podstawie wersjonowanych poleceń uruchamiania npm i wersjonowanych danych początkowych. Szukałeś również sposobu na skopiowanie metadanych, ale niestety tego nie widziałem.
Chris,
@Chris dzięki za poinformowanie nas o tym. O ile wiem, jest to nadal otwarte pytanie.
wyścigi
25

Obecnie nie używam Firebase, ale uważam to za siebie. Wygląda na to, że najlepszym rozwiązaniem jest utworzenie całkowicie oddzielnego projektu na konsoli. W starej witrynie Firebase pojawił się post na blogu polecający to, ale wygląda na to, że teraz został usunięty. https://web.archive.org/web/20160310115701/https://www.firebase.com/blog/2015-10-29-managing-development-environments.html

Również ta dyskusja poleca to samo: https://groups.google.com/forum/#!msg/firebase-talk/L7ajIJoHPcA/7dsNUTDlyRYJ

Patrick
źródło
2
Dziękuję za odpowiedź. Posiadanie dwóch oddzielnych projektów jest najprawdopodobniej jedyną opcją. Jednak kopiowanie danych między nimi jest w najlepszym przypadku skomplikowane. Zastanawiam się, czy Firebase Tools może kopiować reguły, konfigurację odbiorców itp. Wydaje mi się, że zajmuje się tylko operacjami związanymi z bazą danych: github.com/firebase/firebase-tools
racs
2
Nie jestem pewien, czy to widziałeś, ale możesz uruchomić swojego programistę na serwerze firebase
krico
2
To jest dokładnie to, co zrobiłem, ale pytanie brzmi: jak skopiować dowolną konfigurację między dwoma środowiskami? Na przykład. zdalne konfiguracje, konfiguracja odbiorców itp.? Dodanie ich ręcznie do środowiska produkcyjnego jest raczej podatne na błędy.
wyścigi
2
Problem, na który się natknąłem, to uwierzytelnianie za pomocą wielu instancji Firebase z tym samym pakietem i podpisem. Konsola nie pozwoli ci dodać tego samego pakietu sha1 do więcej niż jednego projektu, więc może to nie być możliwe. Doktorzy twierdzą, że istnieje obejście przez umieszczenie na białej liście clientid, ale nie udało mi się to. Innym rozwiązaniem są oddzielne nazwy pakietów (dokładniej „applicationIds)”, ale są też inne komplikacje
Patrick
3
Przeczytaj także: firebase.googleblog.com/2016/08/…
wyścigi
8

Sposób, w jaki to zrobiłem:

  1. Miałem 2 projekty na firebase - jeden dla DEV, drugi dla PROD
  2. Lokalnie moja aplikacja miała również 2 gałęzie - jedną o nazwie DEV, a drugą o nazwie PROD
  3. W mojej gałęzi DEV zawsze mam plik JSON projektu DEV firebase i podobnie dla PROD

W ten sposób nie muszę utrzymywać moich plików JSON.

Kunal Khaire
źródło
1
Rozumiem, ale nie ma ogólnego rozwiązania zadanego pytania zgodnie z najnowszą wersją Firebase. Musisz grać z aktualnymi opcjami i czerpać najlepsze praktyki. Być może moja odpowiedź nie wskazywała na to, ale chcę po prostu pomóc pytającemu w mojej perspektywie.
Kunal Khaire,
5

Ten post na blogu opisuje bardzo proste podejście z typem kompilacji do debugowania i wydania.

W skrócie:

  • Utwórz nową aplikację w Firebase dla każdego typu kompilacji, używając innego sufiksu identyfikatora aplikacji.
  • Skonfiguruj projekt systemu Android przy użyciu najnowszego pliku JSON.
  • Korzystając z applicationIdSuffix, zmień identyfikator aplikacji, aby pasował do różnych aplikacji w Firebase w zależności od typu kompilacji.

=> zobacz post na blogu, aby uzyskać szczegółowy opis.

Jeśli chcesz użyć różnych wersji kompilacji, przeczytaj ten obszerny post na oficjalnym blogu Firebase. Zawiera wiele cennych informacji.

Mam nadzieję, że to pomoże!

Lukas Lechner
źródło
Dzięki za odpowiedź. Udało mi się skonfigurować różne aplikacje, ale nadal szukam metody kopiowania różnych ustawień z aplikacji FB dev do aplikacji FB prod, o co prosiłem w pytaniu. (Np. Zdalna konfiguracja lub ustawienia odbiorców).
wyścigi
2
Pamiętaj, że tworzy to dwie aplikacje w tym samym projekcie, dlatego oddzielisz niektóre usługi, takie jak analityka, ale baza danych będzie współdzielona, ​​więc nie jest to prawdziwe oddzielenie środowisk, jak wyjaśniono tutaj firebase.googleblog.com/2016/08/…
AntPachon
5

Będziesz musiał zarządzać różnymi typami kompilacji

Obserwuj to

  1. Najpierw utwórz nowy projekt w konsoli Firebase o identyfikatorze YOURAPNAME-DEV

  2. Kliknij przycisk „Dodaj aplikację na Androida” i utwórz nową aplikację. Na przykład nazwij go com.yourapp.debug. Nowy plik google-services.json zostanie pobrany automatycznie

  3. W katalogu src projektu utwórz nowy katalog o nazwie „debug” i skopiuj tutaj nowy plik google-services.json

  4. Dodaj to na poziomie modułu build.gradle

    debug {
            applicationIdSuffix ".debug"
        }
    

Teraz podczas tworzenia debugowania zostanie użyty plik google-services.json z folderu „debug”, a podczas tworzenia w trybie wydania plik google-services.json z katalogu głównego modułu będzie brany pod uwagę.

Chetan
źródło
Na wypadek, gdyby ktoś potrzebował oficjalnej dokumentacji, wtyczka Gradle usług Google wie, że musi szukać srcpliku google-services.json w podkatalogu buildType, jak wyjaśniono tutaj developers.google.com/android/guides/ ...
Michael Osofsky
4

Aby rozwiązać ten problem w mojej sytuacji, stworzyłem trzy projekty Firebase, każdy z tym samym projektem na Androida (tj. Taki sam applicationIdbez korzystania z applicationIdSuffixsugerowanych przez innych). W rezultacie powstały trzy pliki google-services.json, które zapisałem na moim serwerze Continuous Integration (CI) jako niestandardowe zmienne środowiskowe . Na każdym etapie kompilacji (dev / staging / prod) użyłem odpowiedniego pliku google-services.json.

W przypadku projektu Firebase skojarzonego z dev, w jego projekcie na Androida dodałem odcisk cyfrowy certyfikatu debugowania SHA. Ale do inscenizacji i prod mam po prostu podpisać plik APK.

Oto uproszczona wersja, .gitlab-ci.ymlktóra działała w tej konfiguracji:

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

Jestem zadowolony z tego rozwiązania, ponieważ nie opiera się na sztuczkach build.gradle, które moim zdaniem są zbyt nieprzejrzyste i przez to trudne do utrzymania. Na przykład, kiedy próbowałem podejść przy użyciu applicationIdSuffixi różnych metod buildType, stwierdziłem, że nie mogę uruchomić testów instrumentalnych ani nawet skompilować, gdy próbowałem zmienić typy kompilacji za pomocą testBuildType. Android wydawał się nadawać specjalne właściwości, debug buildTypektórych nie mogłem zrozumieć.

Praktycznie, z mojego doświadczenia wynika, że ​​skrawki CI są dość przejrzyste i łatwe w utrzymaniu. Rzeczywiście, podejście, które opisałem, zadziałało: kiedy uruchomiłem każdy z pakietów APK wygenerowanych przez CI na emulatorze, krok „Uruchom aplikację, aby zweryfikować instalację” konsoli Firebase wyszedł z

Sprawdzanie, czy aplikacja komunikowała się z naszymi serwerami. Może być konieczne odinstalowanie i ponowne zainstalowanie aplikacji.

do:

Gratulacje, pomyślnie dodałeś Firebase do swojej aplikacji!

dla wszystkich trzech aplikacji, ponieważ uruchamiałem je pojedynczo w emulatorze.

Michael Osofsky
źródło
Dziękuję za cały ten szczegółowy opis, Michael. Udało mi się osiągnąć ten sam rezultat, po prostu dodając oddzielne smaki i kopiując odpowiedni plik google-services.json do folderów dla każdego smaku. Jednak to nie było moje pytanie, przeczytaj je ponownie.
wyścigi
Zgadzam się z @racs, ale niestety, kiedy napisałem stackoverflow.com/questions/37450439/… , zostało to oznaczone jako duplikat twojego pytania przez stackoverflow.com/users/807126/doug-stevenson
Michael Osofsky
1
Doug ... Co zrobiłeś! : Nie mam nic przeciwko twojej odpowiedzi tutaj, jestem pewien, że jest to pomocne dla niektórych osób, które szukają rozwiązania dla oddzielnego środowiska.
wyścigi
tak, szukaliśmy rozwiązania dla naszej aplikacji mobilnej, które wymaga oddzielnych środowisk z usługą Firebase. To dla nas zdecydowanie dobry punkt wyjścia. Spróbujemy to.
LT
2

Firebase ma stronę na ten temat, na której opisano, jak skonfigurować ją na potrzeby programowania i produkcji

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

Ustawianie konfiguracji środowiska dla projektu Aby przechowywać dane środowiska, możesz użyć funkcji Firebase: config: set polecenie w interfejsie wiersza polecenia Firebase. Każdy klucz może mieć przestrzeń nazw przy użyciu kropek do grupowania powiązanej konfiguracji. Pamiętaj, że w kluczach akceptowane są tylko małe litery; wielkie litery nie są dozwolone.

Na przykład, aby przechowywać identyfikator klienta i klucz API dla „niektórych usług”, możesz uruchomić:

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

Pobierz bieżącą konfigurację środowiska Aby sprawdzić, co jest aktualnie przechowywane w konfiguracji środowiska dla twojego projektu, możesz użyć funkcji firebase: config: get. Wyświetli JSON coś takiego:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}
Derek Dawson
źródło
1
Rozwiązuje się na 404. Następnym razem dołącz również zawartość!
CorayThan,
1

Aktualizuję tę odpowiedź na podstawie informacji, które właśnie znalazłem.

Krok 1

Na firebase.google.com utwórz swoje różne środowiska (tj. Deweloperskie, staging, prod)


mysite-dev

mysite-staging

mysite-prod


Krok 2

za. Przejdź bezpośrednio do miejsca, które chcesz ustawić jako domyślne (tj. Dev)

b. Biegaćfirebase deploy

do. Po wdrożeniu uruchomfirebase use --add

re. Pojawi się opcja wyboru spośród różnych projektów, które obecnie masz.

Przewiń do projektu, który chcesz dodać: mysite-staging i wybierz go.

mi. Zostaniesz poproszony o podanie aliasu dla tego projektu. Wejdź do inscenizacji .

Uruchom elementy ae ponownie dla prod i dev, aby każde środowisko miało alias


Wiedz, w jakim środowisku się znajdujesz

Biegać firebase use default (mysite-dev)

* dev (mysite-dev)

staging (mysite-staging)

prod (mysite-dev)

(jedno ze środowisk będzie miało gwiazdkę po lewej stronie. To jest to, w którym aktualnie się znajdujesz. Zostanie również podświetlone na niebiesko)


Przełączaj się między środowiskami

Biegnij firebase use staginglub firebase use prodporuszaj się między nimi.

Gdy znajdziesz się w wybranym środowisku, uruchom, firebase deploya projekt zostanie tam wdrożony.

Oto kilka pomocnych linków ...

Dokumentacja CLI

Wdrażanie w wielu środowiskach

Mam nadzieję że to pomoże.

Jared Newnam
źródło
Mówiąc o wielu środowiskach, masz na myśli wiele projektów?
walidvb
0

Sposób, w jaki to robimy, polega na tworzeniu różnych plików kluczy JSON dla różnych środowisk. Użyliśmy funkcji konta usługi zgodnie z zaleceniami Google i mamy jeden plik programistyczny, a drugi do produkcji

wprowadź opis obrazu tutaj

vsingh
źródło
0

Utwórz projekt Tow ze środowiskiem deweloperskim i produkcyjnym w firebase Pobierz plik json z thre

i skonfiguruj SDK zgodnie z: https://firebase.google.com/docs/android/setup Lub dla Crashlytics: https://firebase.google.com/docs/crashlytics/get-started?platform=android

Najpierw umieść odpowiedni plik google_services.json dla każdego buildType w następujących lokalizacjach:

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

Uwaga: Root app / google_services.json Ten plik powinien być tam zgodnie z wariantami kompilacji skopiuj kod json do głównego pliku json

Teraz przygotujmy kilka zadań gradle w pliku build.gradle: app, aby zautomatyzować przenoszenie odpowiedniego pliku google_services.json do app / google_services.json

skopiuj to do pliku 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 "."
}

Świetnie - ale konieczność ręcznego wykonywania tych zadań przed utworzeniem aplikacji jest uciążliwa. Chcielibyśmy, aby powyższe zadanie kopiowania zostało uruchomione jakiś czas wcześniej: assembleDebug lub: assembleRelease jest uruchamiane. Zobaczmy, co się stanie, gdy: assembleRelease zostanie uruchomiona: skopiuj to do pliku / gradlew

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

Zwróć uwagę na zadanie: app: processReleaseGoogleServices. To zadanie jest odpowiedzialne za przetwarzanie głównego pliku google_services.json. Chcemy, aby przetwarzany był prawidłowy plik google_services.json, dlatego musimy natychmiast uruchomić nasze zadanie kopiowania. Dodaj to do swojego build.gradle. Zwróć uwagę na otaczającą wartość afterEvaluate.

skopiuj to do pliku app / Gradle

afterEvaluate {
processDebugGoogleServices.dependsOn switchToDebug
processReleaseGoogleServices.dependsOn switchToRelease
}

Teraz, w dowolnym momencie wywoływana jest funkcja: app: processReleaseGoogleServices, nasze nowo zdefiniowane: app: switchToRelease zostanie wcześniej wywołane. Ta sama logika dla debugowania buildType. Możesz uruchomić: app: assembleRelease, a wersja google_services.json zostanie automatycznie skopiowana do folderu głównego modułu aplikacji.

Shaikh Mohib
źródło
1
Włożyłeś dużo energii w tę odpowiedź, ale 1. to nie ma nic wspólnego z pytaniem (przeczytaj je ponownie), 2. nie musisz kopiować google-services.jsonpliku do katalogu głównego, jeśli go przechowujesz folder ze smakami, który jest w porządku. Zamiast tego assembleReleasemożesz po prostu wywołać assembleTestReleasezadanie.
wyścigi