1. Wprowadzenie
Ostatnia aktualizacja: 16 listopada 2022 r.
Tworzenie aplikacji na Androida za pomocą Firebase i Jetpack Compose
W tym ćwiczeniu z programowania utworzysz aplikację na Androida o nazwie Make It So. Interfejs tej aplikacji jest w całości zbudowany za pomocą Jetpack Compose, czyli nowoczesnego zestawu narzędzi Androida do tworzenia natywnego interfejsu .Jest on intuicyjny i wymaga mniej kodu niż pisanie plików XML i powiązywanie ich z aktywnościami, fragmentami lub widokami.
Pierwszym krokiem do zrozumienia, jak dobrze współpracują ze sobą Firebase i Jetpack Compose, jest poznanie nowoczesnej architektury Androida. Dobra architektura sprawia, że system jest łatwy do zrozumienia, rozwijania i utrzymywania, ponieważ jasno określa, jak są zorganizowane komponenty i jak się ze sobą komunikują. W świecie Androida zalecana architektura to Model – View – ViewModel. Model to warstwa, która uzyskuje dostęp do danych w aplikacji. Widok to warstwa interfejsu, która nie powinna mieć żadnej wiedzy o logice biznesowej. W ViewModelu stosowana jest logika biznesowa, co czasami wymaga wywołania warstwy Model przez ViewModel.
Zdecydowanie zalecamy przeczytanie tego artykułu, aby dowiedzieć się, jak wzorzec Model – View – ViewModel jest stosowany w aplikacji na Androida utworzonej za pomocą Jetpack Compose. Ułatwi to zrozumienie bazy kodu i wykonanie kolejnych kroków.
Co utworzysz
Make It So to prosta aplikacja do tworzenia list zadań do wykonania, która umożliwia dodawanie i edytowanie zadań, dodawanie flag, priorytetów i terminów oraz oznaczanie zadań jako ukończonych. Obrazy poniżej przedstawiają 2 główne strony tej aplikacji: stronę tworzenia zadań i stronę główną z listą utworzonych zadań.
Dodasz niektóre funkcje, których brakuje w tej aplikacji:
- Uwierzytelnianie użytkowników za pomocą adresu e-mail i hasła
- Dodawanie detektora do kolekcji Firestore i reagowanie interfejsu na zmiany
- Dodawanie niestandardowych logów czasu, aby monitorować wydajność określonego kodu w aplikacji
- Utwórz przełącznik funkcji za pomocą Zdalnej konfiguracji i wdrażaj go etapami
Czego się nauczysz
- Jak używać Uwierzytelniania Firebase, Monitorowania wydajności, Zdalnej konfiguracji i Cloud Firestore w nowoczesnej aplikacji na Androida
- Jak dostosować interfejsy API Firebase do architektury MVVM
- Jak odzwierciedlać zmiany wprowadzone za pomocą interfejsów API Firebase w interfejsie Compose
Czego potrzebujesz
- Android Studio Flamingo+
- Emulator Androida z interfejsem API w wersji 21 lub nowszej
- znajomość języka programowania Kotlin,
2. Pobieranie przykładowej aplikacji i konfigurowanie Firebase
Pobieranie kodu przykładowej aplikacji
Sklonuj repozytorium GitHub z wiersza poleceń:
git clone https://github.com/FirebaseExtended/make-it-so-android.git
Tworzenie projektu Firebase
- Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
- Kliknij przycisk, aby utworzyć nowy projekt, a następnie wpisz jego nazwę (np.
Compose Firebase codelab
). - Kliknij Dalej.
- Po wyświetleniu monitu przeczytaj i zaakceptuj warunki usługi Firebase, a potem kliknij Dalej.
- (Opcjonalnie) Włącz w konsoli Firebase pomoc AI (nazywaną „Gemini w Firebase”).
- W tym samouczku potrzebujesz Google Analytics, aby korzystać z zaawansowanych opcji kierowania w Zdalnej konfiguracji, więc pozostaw włączony przełącznik opcji Google Analytics. Aby skonfigurować Google Analytics, postępuj zgodnie z instrukcjami wyświetlanymi na ekranie.
- Kliknij Utwórz projekt, poczekaj, aż projekt zostanie udostępniony, a następnie kliknij Dalej.
Dodawanie aplikacji na Androida do projektu Firebase
W projekcie Firebase możesz zarejestrować różne aplikacje: na Androida, iOS, internetowe, Flutter i Unity.
Wybierz opcję Android, jak widać tutaj:
Następnie wykonaj te czynności:
- Wpisz
com.example.makeitso
jako nazwę pakietu i opcjonalnie pseudonim. W tym ćwiczeniu nie musisz dodawać certyfikatu podpisywania debugowania. - Kliknij Dalej, aby zarejestrować aplikację i uzyskać dostęp do pliku konfiguracyjnego Firebase.
- Kliknij Pobierz google-services.json, aby pobrać plik konfiguracyjny i zapisać go w katalogu
make-it-so-android/app
. - Kliknij Dalej. Pakiety SDK Firebase są już uwzględnione w pliku
build.gradle
w projekcie przykładowym, więc kliknij Dalej, aby przejść do sekcji Dalsze kroki. - Aby zakończyć, kliknij Przejdź do konsoli.
Aby aplikacja Make it So działała prawidłowo, przed przejściem do kodu musisz wykonać w konsoli 2 czynności: włączyć dostawców uwierzytelniania i utworzyć bazę danych Firestore.
Konfigurowanie uwierzytelniania
Najpierw włączmy uwierzytelnianie, aby użytkownicy mogli logować się w aplikacji:
- W menu Build (Tworzenie) wybierz Authentication (Uwierzytelnianie), a następnie kliknij Get Started (Rozpocznij).
- Na karcie Metoda logowania wybierz E-mail/hasło i włącz tę opcję.
- Następnie kliknij Dodaj nowego dostawcę i wybierz oraz włącz Anonimowy.
Konfigurowanie Cloud Firestore
Następnie skonfiguruj Firestore. Będziesz używać Firestore do przechowywania zadań zalogowanego użytkownika. Każdy użytkownik otrzyma własny dokument w kolekcji bazy danych.
- W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a następnie wybierz Baza danych Firestore.
- Kliknij Utwórz bazę danych.
- W polu Identyfikator bazy danych pozostaw wartość
(default)
. - Wybierz lokalizację bazy danych i kliknij Dalej.
W przypadku prawdziwej aplikacji wybierz lokalizację, która jest blisko użytkowników. - Kliknij Uruchom w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł zabezpieczeń.
W kolejnych krokach tej sekcji dodasz reguły zabezpieczeń, aby chronić swoje dane. Nierozpowszechniajani nie udostępniaj publicznie aplikacji bez dodania reguł bezpieczeństwa do bazy danych. - Kliknij Utwórz.
Poświęćmy chwilę na utworzenie niezawodnych reguł zabezpieczeń dla bazy danych Firestore.
- Otwórz panel Firestore i kliknij kartę Reguły.
- Zaktualizuj reguły zabezpieczeń, aby wyglądały tak:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /tasks/{document} {
allow create: if request.auth != null;
allow read, update, delete: if request.auth != null
&& resource.data.userId == request.auth.uid
&& request.data.userId == resource.data.userId;
}
}
}
Zasady te mówią, że każdy zalogowany użytkownik aplikacji może utworzyć dla siebie dokument w dowolnej kolekcji. Po utworzeniu dokumentu tylko użytkownik, który go utworzył, będzie mógł go wyświetlać, aktualizować i usuwać.
Uruchom aplikację
Teraz możesz uruchomić aplikację. Otwórz folder make-it-so-android/start
w Android Studio i uruchom aplikację (możesz to zrobić za pomocą emulatora Androida lub prawdziwego urządzenia z Androidem).
3. Uwierzytelnianie Firebase
Którą funkcję chcesz dodać?
W obecnej wersji aplikacji przykładowej Make It So użytkownik może zacząć korzystać z aplikacji bez konieczności logowania się. W tym celu używa uwierzytelniania anonimowego. Konta anonimowe nie umożliwiają jednak użytkownikowi dostępu do danych na innych urządzeniach ani nawet w przyszłych sesjach. Uwierzytelnianie anonimowe jest przydatne w przypadku wstępnego wprowadzania użytkowników, ale zawsze należy im udostępniać możliwość przejścia na inną formę logowania. W tym samouczku dodasz do aplikacji Make It So uwierzytelnianie za pomocą adresu e-mail i hasła.
Czas na kodowanie!
Gdy użytkownik utworzy konto, wpisując adres e-mail i hasło, musisz poprosić interfejs Firebase Authentication API o dane logowania e-mail, a następnie połączyć nowe dane logowania z kontem anonimowym. Otwórz plik AccountServiceImpl.kt
w Android Studio i zaktualizuj funkcję linkAccount
, aby wyglądała tak:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
Teraz otwórz plik SignUpViewModel.kt
i wywołaj funkcję usługi linkAccount
w bloku launchCatching
funkcji onSignUpClick
:
screens/sign_up/SignUpViewModel.kt
launchCatching {
accountService.linkAccount(email, password)
openAndPopUp(SETTINGS_SCREEN, SIGN_UP_SCREEN)
}
Najpierw próbuje się uwierzytelnić, a jeśli wywołanie się powiedzie, przechodzi do następnego ekranu (SettingsScreen
). Ponieważ wywołania te są wykonywane w bloku launchCatching
, jeśli w pierwszym wierszu wystąpi błąd, wyjątek zostanie przechwycony i obsłużony, a drugi wiersz nie zostanie w ogóle osiągnięty.
Gdy SettingsScreen
zostanie ponownie otwarty, musisz się upewnić, że opcje Zaloguj się i Utwórz konto zniknęły, ponieważ użytkownik jest już uwierzytelniony. Aby to zrobić, sprawimy, że funkcja SettingsViewModel
będzie nasłuchiwać stanu bieżącego użytkownika (dostępnego w AccountService.kt
), aby sprawdzić, czy konto jest anonimowe. Aby to zrobić, zaktualizuj uiState
w SettingsViewModel.kt
, aby wyglądało tak:
screens/settings/SettingsViewModel.kt
val uiState = accountService.currentUser.map {
SettingsUiState(it.isAnonymous)
}
Ostatnią rzeczą, jaką musisz zrobić, jest zaktualizowanie uiState
w SettingsScreen.kt
, aby zbierać stany emitowane przez SettingsViewModel
:
screens/settings/SettingsScreen.kt
val uiState by viewModel.uiState.collectAsState(
initial = SettingsUiState(false)
)
Teraz za każdym razem, gdy użytkownik się zmieni, komponent SettingsScreen
zostanie ponownie skomponowany, aby wyświetlić opcje zgodnie z nowym stanem uwierzytelniania użytkownika.
Czas na testowanie!
Uruchom Make it So i otwórz ustawienia, klikając ikonę koła zębatego w prawym górnym rogu ekranu. Następnie kliknij opcję utworzenia konta:
Aby utworzyć konto, wpisz prawidłowy adres e-mail i silne hasło. Powinno to zadziałać i przekierować Cię na stronę ustawień, na której zobaczysz 2 nowe opcje: wylogowanie się i usunięcie konta. Nowe konto utworzone w panelu Uwierzytelnianie w konsoli Firebase możesz sprawdzić, klikając kartę Użytkownicy.
4. Cloud Firestore
Którą funkcję chcesz dodać?
W przypadku Cloud Firestore dodasz odbiornik do kolekcji Firestore, w której są przechowywane dokumenty reprezentujące zadania wyświetlane w aplikacji Make it So. Po dodaniu tego odbiornika będziesz otrzymywać wszystkie aktualizacje wprowadzane w tej kolekcji.
Czas na kodowanie!
Zaktualizuj Flow
dostępny w StorageServiceImpl.kt
, aby wyglądał tak:
model/service/impl/StorageServiceImpl.kt
override val tasks: Flow<List<Task>>
get() =
auth.currentUser.flatMapLatest { user ->
firestore.collection(TASK_COLLECTION).whereEqualTo(USER_ID_FIELD, user.id).dataObjects()
}
Ten kod dodaje do kolekcji zadań odbiornik na podstawie user.id
. Każde zadanie jest reprezentowane przez dokument w kolekcji o nazwie tasks
, a każdy z nich ma pole o nazwie userId
. Pamiętaj, że jeśli stan currentUser
się zmieni (np. wylogujesz się), zostanie wyemitowane nowe zdarzenie Flow
.
Teraz musisz sprawić, aby wartość Flow
w TasksViewModel.kt
była taka sama jak w usłudze:
screens/tasks/TasksViewModel.kt
val tasks = storageService.tasks
Ostatnim krokiem będzie uświadomienie composable function
w TasksScreens.kt
, czyli interfejsu, o tym procesie i zebranie go jako stanu. Za każdym razem, gdy stan się zmieni, funkcja kompozycyjna automatycznie się ponownie skomponuje i wyświetli użytkownikowi najnowszy stan. Dodaj to do TasksScreen composable function
:
screens/tasks/TasksScreen.kt
val tasks = viewModel
.tasks
.collectAsStateWithLifecycle(emptyList())
Gdy funkcja kompozycyjna uzyska dostęp do tych stanów, możesz zaktualizować LazyColumn
(czyli strukturę, której używasz do wyświetlania listy na ekranie), aby wyglądała tak:
screens/tasks/TasksScreen.kt
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem( [...] )
}
}
Czas na testowanie!
Aby sprawdzić, czy wszystko działa, dodaj nowe zadanie w aplikacji (kliknij przycisk dodawania w prawym dolnym rogu ekranu). Po utworzeniu zadania powinno ono pojawić się w kolekcji Firestore w konsoli Firestore. Jeśli zalogujesz się w Make it So na innych urządzeniach za pomocą tego samego konta, będziesz mieć możliwość edytowania zadań do wykonania i obserwowania ich aktualizacji na wszystkich urządzeniach w czasie rzeczywistym.
5. Monitorowanie wydajności
Którą funkcję chcesz dodać?
Wydajność jest bardzo ważna, ponieważ użytkownicy prawdopodobnie zrezygnują z korzystania z aplikacji, jeśli nie będzie ona działać dobrze i wykonanie prostego zadania zajmie im zbyt dużo czasu. Dlatego czasami warto zbierać dane o konkretnej ścieżce, którą użytkownik pokonuje w aplikacji. Aby Ci w tym pomóc, Monitorowanie wydajności Firebase oferuje niestandardowe ślady. Aby dodać niestandardowe logi czasu i mierzyć wydajność różnych fragmentów kodu w Make it So, wykonaj te czynności:
Czas na kodowanie!
Jeśli otworzysz plik Performance.kt
, zobaczysz funkcję wbudowaną o nazwie trace. Ta funkcja wywołuje interfejs Performance Monitoring API, aby utworzyć ślad niestandardowy, przekazując nazwę śladu jako parametr. Drugi parametr to blok kodu, który chcesz monitorować. Domyślne dane zbierane w przypadku każdego śledzenia to czas potrzebny na jego pełne wykonanie:
model/service/Performance.kt
inline fun <T> trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block)
Możesz wybrać części kodu, które Twoim zdaniem warto zmierzyć, i dodać do nich niestandardowe ślady. Oto przykład dodawania niestandardowego śledzenia do funkcji linkAccount
, którą widzieliśmy wcześniej (w AccountServiceImpl.kt
) w tym laboratorium:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String): Unit =
trace(LINK_ACCOUNT_TRACE) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
Teraz Twoja kolej. Dodaj niestandardowe ślady do aplikacji Make it So i przejdź do następnej sekcji, aby sprawdzić, czy działa ona zgodnie z oczekiwaniami.
Czas na testowanie!
Po dodaniu niestandardowych śladów uruchom aplikację i kilkakrotnie użyj funkcji, które chcesz mierzyć. Następnie otwórz konsolę Firebase i wyświetl panel wydajności. U dołu ekranu znajdziesz 3 karty: Żądania sieciowe, Ślady niestandardowe i Renderowanie ekranu.
Otwórz kartę Niestandardowe logi czasu i sprawdź, czy wyświetlają się na niej logi czasu dodane w bazie kodu oraz czy możesz zobaczyć, ile czasu zwykle zajmuje wykonanie tych fragmentów kodu.
6. Zdalna konfiguracja
Którą funkcję chcesz dodać?
Zdalna konfiguracja ma wiele zastosowań, od zdalnej zmiany wyglądu aplikacji po konfigurowanie różnych zachowań dla różnych segmentów użytkowników. W tym laboratorium kodowania użyjesz Zdalnej konfiguracji, aby utworzyć przełącznik funkcji, który będzie wyświetlać lub ukrywać nową funkcję edytowania zadania w aplikacji Make it So.
Czas na kodowanie!
Najpierw musisz utworzyć konfigurację w konsoli Firebase. Aby to zrobić, otwórz panel Zdalnej konfiguracji i kliknij przycisk Dodaj parametr. Wypełnij pola zgodnie z poniższym obrazem:
Po wypełnieniu wszystkich pól możesz kliknąć przycisk Zapisz, a następnie Opublikuj. Teraz, gdy parametr został utworzony i jest dostępny w bazie kodu, musisz dodać do aplikacji kod, który będzie pobierać nowe wartości. Otwórz plik ConfigurationServiceImpl.kt
i zaktualizuj implementację tych 2 funkcji:
model/service/impl/ConfigurationServiceImpl.kt
override suspend fun fetchConfiguration(): Boolean {
return remoteConfig.fetchAndActivate().await()
}
override val isShowTaskEditButtonConfig: Boolean
get() = remoteConfig[SHOW_TASK_EDIT_BUTTON_KEY].asBoolean()
Pierwsza funkcja pobiera wartości z serwera i jest wywoływana natychmiast po uruchomieniu aplikacji w SplashViewModel.kt
. To najlepszy sposób, aby mieć pewność, że od samego początku na wszystkich ekranach będą dostępne najbardziej aktualne wartości. Zmiana interfejsu lub działania aplikacji w momencie, gdy użytkownik wykonuje jakąś czynność, nie jest dobrym rozwiązaniem.
Druga funkcja zwraca wartość logiczną opublikowaną dla parametru, który został właśnie utworzony w konsoli. Musisz też pobrać te informacje w TasksViewModel.kt
, dodając do funkcji loadTaskOptions
ten kod:
screens/tasks/TasksViewModel.kt
fun loadTaskOptions() {
val hasEditOption = configurationService.isShowTaskEditButtonConfig
options.value = TaskActionOption.getOptions(hasEditOption)
}
Pobierasz wartość z pierwszego wiersza i używasz jej do wczytywania opcji menu dla elementów zadania w drugim wierszu. Jeśli wartość to false
, oznacza to, że menu nie będzie zawierać opcji edycji. Teraz, gdy masz już listę opcji, musisz zadbać o to, aby interfejs użytkownika wyświetlał ją prawidłowo. Podczas tworzenia aplikacji za pomocą Jetpack Compose musisz poszukać funkcji composable function
, która określa wygląd interfejsu TasksScreen
. Otwórz plik TasksScreen.kt
i zaktualizuj LazyColum
, aby wskazywał opcje dostępne w TasksViewModel.kt
:
screens/tasks/TasksScreen.kt
val options by viewModel.options
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem(
options = options,
[...]
)
}
}
TaskItem
to kolejny composable function
, który określa wygląd interfejsu pojedynczego zadania. Każde zadanie ma menu z opcjami, które wyświetla się, gdy użytkownik kliknie ikonę z 3 kropkami na końcu zadania.
Czas na testowanie!
Możesz teraz uruchomić aplikację. Sprawdź, czy wartość opublikowana w konsoli Firebase jest zgodna z zachowaniem aplikacji:
- Jeśli jest to
false
, po kliknięciu ikony z 3 kropkami powinny być widoczne tylko 2 opcje: - Jeśli jest to
true
, po kliknięciu ikony z 3 kropkami powinny pojawić się 3 opcje:
Spróbuj kilka razy zmienić wartość w Konsoli i ponownie uruchomić aplikację. Właśnie w ten prosty sposób możesz wprowadzać nowe funkcje w aplikacji za pomocą Zdalnej konfiguracji.
7. Gratulacje
Udało Ci się utworzyć aplikację na Androida za pomocą Firebase i Jetpack Compose.
Do aplikacji na Androida, która została w całości utworzona za pomocą Jetpack Compose na potrzeby interfejsu, dodano Uwierzytelnianie Firebase, Monitorowanie wydajności, Zdalną konfigurację i Cloud Firestore. Aplikacja została dostosowana do zalecanej architektury MVVM.
Więcej informacji
- Tworzenie aplikacji na Androida za pomocą Firebase i Compose
- Dodawanie uwierzytelniania Firebase do aplikacji Jetpack Compose
- Dodawanie Cloud Firestore do aplikacji Jetpack Compose
- Dodawanie do aplikacji na Androida, która została utworzona za pomocą Firebase i Compose, funkcji Coroutines i Flow
- Dodawanie Monitorowania wydajności Firebase do aplikacji Jetpack Compose
- Dodawanie Zdalnej konfiguracji Firebase do aplikacji Jetpack Compose