Эта кодовая лаборатория является частью курса Advanced Android in Kotlin. Вы получите максимальную отдачу от этого курса, если будете последовательно работать с лабораториями кода, но это не обязательно. Все кодовые лаборатории курса перечислены на целевой странице Advanced Android in Kotlin codelabs .
Введение
При создании приложения для Android есть много преимуществ, которые может дать поддержка входа для ваших пользователей. Разрешая пользователям создавать удостоверения в вашем приложении, вы можете предоставить им больше способов взаимодействия с приложением.
Благодаря персонализированным учетным записям пользователи могут настраивать свои действия в приложении, взаимодействовать с другими пользователями, а также сохранять и передавать свои данные, если они используют приложение на другом устройстве (например, в Интернете или на новом телефоне).
В этой лаборатории кода вы изучите основы поддержки входа в систему для вашего приложения с помощью библиотеки FirebaseUI . Среди прочего, библиотека FirebaseUI упрощает работу разработчиков, которые хотят создать процесс входа в систему, и выполняет работу по управлению учетными записями пользователей за вас.
Что вы уже должны знать
- Основы создания приложения для Android
- LiveData и ViewModel
Что вы узнаете
- Как добавить Firebase в свой проект
- Как поддерживать вход в приложение для Android
- Как наблюдать за текущим статусом аутентификации вашего приложения
- Как выйти из пользователей
Что ты будешь делать
- Используйте консоль Firebase, чтобы интегрировать Firebase в свое приложение.
- Реализуйте функцию входа в систему.
- Добавьте настройки в приложение для пользователей, которые вошли в систему.
- Реализовать выход пользователей из системы.
Узнайте больше о LiveData и ViewModel
Для приложения в этой кодовой лаборатории вам необходимо базовое понимание LiveData и ViewModel. Прочтите обзоры LiveData и ViewModel , если хотите получить краткий обзор этих концепций.
Вы также можете пройти курс «Разработка приложений для Android с помощью Kotlin», чтобы узнать об основных темах Android, с которыми вы столкнетесь в рамках этой лаборатории кода. Этот курс доступен как в виде курса Udacity, так и в виде курса codelabs .
В этой лабораторной работе вы создадите приложение, отображающее забавные факты об Android. Что еще более важно, в приложении будет кнопка входа/выхода . Когда пользователь входит в приложение, любой отображаемый факт Android будет включать приветствие для пользователя, чтобы добавить немного персонализации.
Скачать пример приложения можно одним из следующих способов:
... или клонируйте репозиторий GitHub из командной строки с помощью следующей команды и переключитесь на start
ветвь репозитория:
$ git clone https://github.com/googlecodelabs/android-kotlin-login
Важно: поскольку вы будете интегрировать приложение для использования Firebase, начальное приложение требует некоторой настройки, чтобы оно могло быть построено и запущено. Вы сделаете это на следующем шаге лаборатории кода.
Шаг 1. Создайте проект Firebase.
Прежде чем вы сможете добавить Firebase в свое Android-приложение, вам необходимо создать проект Firebase для подключения к вашему Android-приложению.
- В консоли Firebase нажмите Добавить проект.
- Выберите или введите имя проекта . Вы можете назвать свой проект как угодно, но постарайтесь выбрать имя, соответствующее приложению, которое вы создаете.
- Нажмите Продолжить .
- Вы можете пропустить настройку Google Analytics и выбрать вариант « Не прямо сейчас ».
- Нажмите «Создать проект» , чтобы завершить настройку проекта Firebase.
Шаг 2. Зарегистрируйте свое приложение в Firebase
Теперь, когда у вас есть проект Firebase, вы можете добавить в него свое Android-приложение.
- В центре страницы обзора проекта консоли Firebase щелкните значок Android , чтобы запустить рабочий процесс установки.
- Введите идентификатор приложения вашего приложения в поле имени пакета Android . Убедитесь, что вы вводите идентификатор, который использует ваше приложение, так как вы не можете добавить или изменить это значение после того, как вы зарегистрировали свое приложение в своем проекте Firebase.
- Идентификатор приложения иногда называют именем пакета .
- Найдите этот идентификатор приложения в файле Gradle своего модуля (уровня приложения), обычно это
app/build.gradle
(пример идентификатора:com.yourcompany.yourproject
). - Введите сертификат подписи отладки SHA-1. Вы можете сгенерировать этот ключ, введя следующую команду в терминале командной строки.
keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v -storepass android
- Щелкните Зарегистрировать приложение .
Шаг 3. Добавьте файл конфигурации Firebase в свой проект.
Добавьте файл конфигурации Firebase Android в свое приложение:
- Нажмите Загрузить google-services.json , чтобы получить файл конфигурации Firebase Android (
google-services.json
).
- Вы можете снова загрузить файл конфигурации Firebase Android в любое время.
- Убедитесь, что файл конфигурации не дополнен дополнительными символами и должен называться только
google-services.json
.
- Переместите файл конфигурации в каталог модуля (уровня приложения) вашего приложения.
Шаг 4. Настройте проект Android для включения продуктов Firebase.
- Чтобы включить продукты Firebase в своем приложении, добавьте плагин google-services в свои файлы Gradle.
- В файле Gradle корневого уровня (уровня проекта) (
build.gradle
) добавьте правила для включения подключаемого модуля Google Services. Убедитесь, что у вас также есть репозиторий Google Maven.
build.gradle
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
}
dependencies {
// ...
// Add the following line:
classpath 'com.google.gms:google-services:4.3.0' // Google Services plugin
}
}
allprojects {
// ...
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
// ...
}
}
- В файле Gradle вашего модуля (уровня приложения) (обычно
app/build.gradle
) добавьте строку в конец файла.
приложение/build.gradle
apply plugin: 'com.android.application'
android {
// ...
}
// Add the following line to the bottom of the file:
apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin
Шаг 4: Добавьте зависимость от Firebase
В этой кодовой лаборатории основная причина интеграции Firebase — возможность создавать пользователей и управлять ими. Для этого вам нужно добавить библиотеку Firebase, которая позволит вам реализовать вход в систему.
- Добавьте следующую зависимость в файл
build.gradle (Module:app)
, чтобы вы могли использовать SDK в своем приложении. SDKfirebase-auth
позволяет управлять аутентифицированными пользователями вашего приложения.
приложение/build.gradle:
implementation 'com.firebaseui:firebase-ui-auth:5.0.0'
- Синхронизируйте свой проект с файлами gradle, чтобы убедиться, что все зависимости доступны для вашего приложения. Если не появится запрос, выберите «Файл» > «Синхронизировать проект с файлами Gradle» в Android Studio или на панели инструментов.
Шаг 5. Запустите приложение и проверьте код
- Запустите приложение на эмуляторе или физическом устройстве, чтобы убедиться, что ваша среда успешно настроена для начала разработки.
В случае успеха вы должны увидеть на главном экране забавный факт об Android и кнопку входа в верхний левый угол. Нажатие кнопки входа пока ничего не делает.
На высоком уровне это приложение с одним действием с несколькими фрагментами. MainFragment
содержит весь пользовательский интерфейс, который вы видите на экране ниже. (Вы будете работать с LoginFragment
и SettingsFragment
в последующей лаборатории кода.)
- Ознакомьтесь с кодом. В частности, обратите внимание:
-
FirebaseUserLiveData
— это класс, который вы будете реализовывать для наблюдения за текущим пользователем Firebase, связанным с приложением. Вы будете использовать экземплярFirebaseAuth
в качестве точки входа для получения этой информации о пользователе на более позднем этапе. -
MainFragment
привязан кLoginViewModel
.LoginViewModel
— это класс, который вы будете реализовывать, чтобы использоватьFirebaseUserLiveData
для создания переменнойauthenticationState
. Используя эту переменнуюauthenticationState
,MainFragment
может наблюдать за значением для соответствующего обновления пользовательского интерфейса.
На этом шаге вы будете использовать консоль Firebase, чтобы настроить методы аутентификации, которые вы хотите, чтобы ваше приложение поддерживало. В этой лаборатории кода вы сосредоточитесь на том, чтобы позволить пользователям входить в систему с помощью предоставленного ими адреса электронной почты или их учетной записи Google.
- Перейдите в консоль Firebase . (Примечание. Если вы все еще находитесь в рабочем процессе добавления Firebase, нажмите X в левом верхнем углу, чтобы вернуться в консоль.
- Выберите свой проект, если вы еще не в своем проекте.
- Откройте левую панель навигации и выберите « Разработка» > «Аутентификация».
- Выберите вкладку « Метод входа » на верхней панели навигации.
- Нажмите на строку « Электронная почта/пароль ».
- Во всплывающем окне переключите переключатель « Включено » и нажмите « Сохранить ».
- Аналогичным образом нажмите на строку Google .
- Переключите переключатель « Включено », введите адрес электронной почты службы поддержки проекта и нажмите « Сохранить » .
В этой задаче вы реализуете функцию входа в систему для своих пользователей.
- Откройте
MainFragment.kt
. - В
MainFragment
обратите внимание наauth_button
. В настоящее время он не настроен для обработки любого пользовательского ввода. - В
onViewCreated(),
добавьтеonClickListener
вauth_button
для вызоваlaunchSignInFlow()
.
MainFragment.kt
binding.authButton.setOnClickListener { launchSignInFlow() }
- Найдите метод
launchSignInFlow()
вMainFragment.kt
. В настоящее время он содержитTODO
. - Выполните
launchSignInFlow()
, как показано ниже.
MainFragment.kt
private fun launchSignInFlow() {
// Give users the option to sign in / register with their email or Google account.
// If users choose to register with their email,
// they will need to create a password as well.
val providers = arrayListOf(
AuthUI.IdpConfig.EmailBuilder().build(), AuthUI.IdpConfig.GoogleBuilder().build()
// This is where you can provide more ways for users to register and
// sign in.
)
// Create and launch sign-in intent.
// We listen to the response of this activity with the
// SIGN_IN_REQUEST_CODE
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
MainFragment.SIGN_IN_REQUEST_CODE
)
}
Это позволяет пользователям регистрироваться и входить в систему со своим адресом электронной почты или учетной записью Google. Если пользователь решит зарегистрироваться со своим адресом электронной почты, созданная им комбинация адреса электронной почты и пароля будет уникальной для вашего приложения. Это означает, что они смогут войти в ваше приложение с комбинацией адреса электронной почты и пароля, но это не означает, что они также могут войти в любое другое приложение, поддерживаемое Firebase, с теми же учетными данными.
- В
MainFragment.kt
вы можете прослушивать результат процесса входа, реализуя методonActivityResult()
, как показано ниже. Поскольку вы начали процесс входа с помощьюSIGN_IN_REQUEST_CODE
, вы также можете прослушать результат процесса входа, отфильтровав, когдаSIGN_IN_REQUEST_CODE
передается обратно вonActivityResult()
. Начните с некоторых операторов журнала, чтобы узнать, успешно ли пользователь вошел в систему.
MainFragment.kt
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SIGN_IN_REQUEST_CODE) {
val response = IdpResponse.fromResultIntent(data)
if (resultCode == Activity.RESULT_OK) {
// User successfully signed in
Log.i(TAG, "Successfully signed in user ${FirebaseAuth.getInstance().currentUser?.displayName}!")
} else {
// Sign in failed. If response is null the user canceled the
// sign-in flow using the back button. Otherwise check
// response.getError().getErrorCode() and handle the error.
Log.i(TAG, "Sign in unsuccessful ${response?.error?.errorCode}")
}
}
}
Теперь ваше приложение должно поддерживать регистрацию и вход пользователей!
- Запустите приложение и убедитесь, что при нажатии на кнопку входа открывается экран входа в систему.
- Теперь вы можете войти в систему, используя свой адрес электронной почты и пароль, или свою учетную запись Google.
- Пользовательский интерфейс не изменится после входа в систему (вы обновите пользовательский интерфейс на следующем шаге), но если все работает правильно, вы должны увидеть сообщение в журнале.
Successfully signed in user ${your name}!
после прохождения процедуры регистрации. - Вы также можете зайти в консоль Firebase и перейти в раздел « Разработка» > «Аутентификация» > «Пользователи» , чтобы убедиться, что в приложении теперь есть один зарегистрированный пользователь.
- Обратите внимание, что когда пользователи создают учетную запись для вашего приложения, эта учетная запись привязывается только к вашему приложению, а не к какому-либо приложению, которое использует Firebase для входа в систему.
В этой задаче вы реализуете обновление пользовательского интерфейса на основе состояния проверки подлинности. Когда пользователь вошел в систему, вы можете персонализировать его домашний экран, отображая его имя. Вы также обновите кнопку входа в систему, чтобы она стала кнопкой выхода, когда пользователь входит в систему.
- Откройте класс
FirebaseUserLiveData.kt
, который уже создан для вас. Первое, что вам нужно сделать, это предоставить другим классам в приложении способ узнать, когда пользователь вошел в систему или вышел из нее. Однако класс пока ничего не делает, так как значениеLiveData
не обновляется. - Поскольку вы используете библиотеку
FirebaseAuth
, вы можете прослушивать изменения вошедшего в систему пользователя с помощью обратного вызоваFirebaseUser.AuthStateListener
, который реализован для вас как часть библиотеки FirebaseUI. Этот обратный вызов запускается всякий раз, когда пользователь входит или выходит из вашего приложения. - Обратите внимание, что
FirebaseUserLiveData.kt
определяет переменнуюauthStateListener
. Вы будете использовать эту переменную для хранения значенияLiveData
. ПеременнаяauthStateListener
была создана, чтобы вы могли правильно запускать и прекращать прослушивание изменений в состоянии аутентификации в зависимости от состояния вашего приложения. Например, если пользователь переводит приложение в фоновый режим, приложение должно перестать прослушивать изменения состояния аутентификации, чтобы предотвратить любые потенциальные утечки памяти. - Обновите
authStateListener
, чтобы значение вашегоFirebaseUserLiveData
соответствовало текущему пользователю Firebase.
FirebaseUserLiveData.kt
private val authStateListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
value = firebaseAuth.currentUser
}
- Откройте
LoginViewModel.kt
. - В
LoginViewModel.kt
создайте переменнуюauthenticationState
на основе объектаFirebaseUserLiveData
, который вы только что реализовали. Создав эту переменнуюauthenticationState
, другие классы теперь могут запрашивать, вошел ли пользователь в систему или нет, черезLoginViewModel
.
LoginViewModel.kt
val authenticationState = FirebaseUserLiveData().map { user ->
if (user != null) {
AuthenticationState.AUTHENTICATED
} else {
AuthenticationState.UNAUTHENTICATED
}
}
- Откройте
MainFragment.kt.
- В
MainFragment.kt
observeAuthenticationState()
вы можете использовать переменнуюauthenticationState
, которую вы только что добавили вLoginViewModel
и соответствующим образом изменить пользовательский интерфейс. Если есть зарегистрированный пользователь,authButton
должен отображать Logout .
MainFragment.kt
private fun observeAuthenticationState() {
val factToDisplay = viewModel.getFactToDisplay(requireContext())
viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
when (authenticationState) {
LoginViewModel.AuthenticationState.AUTHENTICATED -> {
binding.authButton.text = getString(R.string.logout_button_text)
binding.authButton.setOnClickListener {
// TODO implement logging out user in next step
}
// TODO 2. If the user is logged in,
// you can customize the welcome message they see by
// utilizing the getFactWithPersonalization() function provided
}
else -> {
// TODO 3. Lastly, if there is no logged-in user,
// auth_button should display Login and
// launch the sign in screen when clicked.
}
}
})
}
- Если пользователь вошел в систему, вы также можете настроить приветственное сообщение, которое он увидит, используя
getFactWithPersonalization()
, предоставленную вMainFragment
.
MainFragment.kt
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
- Наконец, если нет пользователя, вошедшего в систему (когда
authenticationState
отличается отLoginViewModel.AuthenticationState.AUTHENTICATED
),auth_button
должен отображать Login и запускать экран входа при нажатии. Также не должно быть никакой персонализации отображаемого сообщения.
MainFragment.kt
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener { launchSignInFlow() }
binding.welcomeText.text = factToDisplay
После выполнения всех шагов ваш окончательный observeAuthenticationState()
должен выглядеть примерно так, как показано ниже.
MainFragment.kt
private fun observeAuthenticationState() {
val factToDisplay = viewModel.getFactToDisplay(requireContext())
viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
// TODO 1. Use the authenticationState variable you just added
// in LoginViewModel and change the UI accordingly.
when (authenticationState) {
// TODO 2. If the user is logged in,
// you can customize the welcome message they see by
// utilizing the getFactWithPersonalization() function provided
LoginViewModel.AuthenticationState.AUTHENTICATED -> {
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
binding.authButton.text = getString(R.string.logout_button_text)
binding.authButton.setOnClickListener {
// TODO implement logging out user in next step
}
}
else -> {
// TODO 3. Lastly, if there is no logged-in user,
// auth_button should display Login and
// launch the sign in screen when clicked.
binding.welcomeText.text = factToDisplay
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener {
launchSignInFlow()
}
}
}
})
}
- Запустите свое приложение. Пользовательский интерфейс должен обновляться в зависимости от того, вошел ли пользователь в систему или нет. Если все работает правильно и вы вошли в систему, главный экран теперь должен приветствовать вас по имени в дополнение к отображению информации об Android. Кнопка « Войти » теперь также должна отображать « Выход» .
В этой задаче вы реализуете функцию выхода из системы.
Поскольку приложение позволяет пользователям входить в систему, оно также должно предоставлять им возможность выхода из системы. Вот пример того, как выйти из системы с помощью всего одной строки кода:
AuthUI.getInstance().signOut(requireContext())
- Откройте
MainFragment.kt
. - В
MainFragment.kt
observeAuthenticationState()
добавьте логику выхода из системы, чтобыauth_button
работала правильно, когда есть пользователь, вошедший в систему. Окончательный результат метода выглядит как код ниже.
MainFragment.kt
private fun observeAuthenticationState() {
val factToDisplay = viewModel.getFactToDisplay(requireContext())
viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
when (authenticationState) {
LoginViewModel.AuthenticationState.AUTHENTICATED -> {
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
binding.authButton.text = getString(R.string.logout_button_text)
binding.authButton.setOnClickListener {
AuthUI.getInstance().signOut(requireContext())
}
}
else -> {
binding.welcomeText.text = factToDisplay
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener {
launchSignInFlow()
}
}
}
})
}
- Запустите приложение.
- Нажмите кнопку « Выход » и убедитесь, что пользователь вышел из системы, а состояние кнопки изменилось на « Войти ».
Вы можете найти окончательную версию готового приложения здесь https://github.com/googlecodelabs/android-kotlin-login .
В этой лаборатории кода вы узнали:
- Как добавить Firebase в свой проект, добавив необходимые зависимости в файл gradle и настроив проект в консоли Firebase.
- Как реализовать вход для вашего приложения с помощью библиотеки FirebaseUI и указать, как вы хотите, чтобы ваши пользователи могли входить в систему. Обратите внимание, что любая учетная запись, которую пользователь создает в вашем приложении, относится только к вашему приложению и не используется всеми приложениями, использующими Firebase для входа в систему.
- Как наблюдать за текущим статусом аутентификации вашего приложения с помощью
LiveData
. - Как разлогинить пользователей.
В этой лаборатории кода были рассмотрены основы поддержки входа в приложение для Android.
В этой лаборатории кода вы разрешили пользователям регистрироваться и входить в систему, используя свой адрес электронной почты. Однако с помощью библиотеки FirebaseUI вы также можете поддерживать другие методы аутентификации, такие как вход с использованием номера телефона. Чтобы узнать больше о возможностях библиотеки FirebaseUI и о том, как использовать другие предоставляемые ею функции, ознакомьтесь со следующими ресурсами:
Чтобы узнать больше о передовых методах входа в систему, ознакомьтесь с этими другими ресурсами:
Лаборатории кода:
Документация для разработчиков Android:
Видео:
Ссылки на другие лаборатории кода в этом курсе см. на целевой странице Advanced Android in Kotlin codelabs.