Este tutorial faz parte do curso Android avançado em Kotlin. Você obterá o máximo valor deste curso se trabalhar com os tutoriais em sequência, mas isso não é obrigatório. Todos os tutoriais do curso estão listados na página de destino Android avançado em Kotlin.
Ao permitir que os usuários façam login e criem uma identidade em seu aplicativo, você pode fornecer a eles mais maneiras de interagir com o aplicativo.
Com contas personalizadas, os usuários podem personalizar sua experiência no aplicativo, interagir com outros usuários e ter seus dados persistidos e transferidos se estiverem usando o aplicativo em outro dispositivo (como web ou um novo telefone).
Neste tutorial, você aprenderá os fundamentos de como oferecer suporte ao login para seu aplicativo usando a biblioteca FirebaseUI. Essa biblioteca torna mais fácil construir um fluxo de login e lida com o trabalho de gerenciamento de contas de usuário para você.
LiveData
e ViewModel
Para o aplicativo neste tutorial, você precisa de um conhecimento básico de LiveData
e ViewModel
. Leia as visões gerais LiveData
e ViewModel
se quiser uma breve visão geral desses conceitos.
Você também pode passar pelo curso Desenvolvimento de aplicativos Android com Kotlin para aprender sobre os tópicos Fundamentos de Android que encontrará como parte deste tutorial. Esse curso está disponível como um curso Udacity e um curso tutoriais.
Neste tutorial, você criará um aplicativo que exibe curiosidades sobre o Android. Mais importante ainda, o aplicativo terá um botão Login/Logout. Quando o usuário está conectado ao aplicativo, qualquer fato Android exibido incluirá uma saudação para o usuário adicionar um toque de personalização.
Baixe o aplicativo de amostra, você pode:
... ou clone o repositório GitHub da linha de comando usando o seguinte comando e mude para o branch start
do repo:
$ git clone https://github.com/googletutoriais/android-kotlin-login
Importante: como você integrará o aplicativo para usar o Firebase, o aplicativo inicial requer algumas configurações para ser compilado e executado. Você fará isso na próxima etapa do tutorial.
Antes de adicionar o Firebase ao seu aplicativo Android, você precisa criar um projeto do Firebase para se conectar ao seu aplicativo Android.
Agora que você tem um projeto Firebase, pode adicionar seu aplicativo Android a ele.
app/build.gradle
(ID de exemplo: com.yourcompany.yourproject
).keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v -storepass android
Adicione o arquivo de configuração do Firebase Android ao seu aplicativo:
google-services.json
).google-services.json
build.gradle
), adicione regras para incluir o plug-in de serviços do Google. Verifique se você também possui o repositório Maven do Google.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
// ...
}
}
app/build.gradle
), adicione uma linha ao final do arquivo.app/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
Neste tutorial, o principal motivo para integrar o Firebase é ter uma maneira de criar e gerenciar usuários. Para isso, você precisa adicionar uma biblioteca do Firebase que permite implementar a funcionalidade de login / logout.
build.gradle (Module:app)
para que você possa usar o SDK em seu aplicativo. O SDK firebase-auth
permite o gerenciamento de usuários autenticados de seu aplicativo.
app / build.gradle:
implementation 'com.firebaseui:firebase-ui-auth:5.0.0'
Execute o aplicativo em um emulador ou dispositivo físico para garantir que seu ambiente seja configurado com êxito para iniciar o desenvolvimento.
Se for bem-sucedido, você verá a tela inicial exibir uma curiosidade sobre o Android e um botão de login no canto superior esquerdo. Tocar no botão de login ainda não faz nada.
Em um alto nível, este é um aplicativo de atividade única com vários fragmentos. O MainFragment
contém toda a IU que você vê na tela abaixo. (Você trabalhará com o LoginFragment
e o SettingsFragment
em um tutorial de acompanhamento.)
Familiarize-se com o código. Em particular, observe o seguinte:
FirebaseUserLiveData
é a classe que você implementará para observar o usuário atual do Firebase associado ao aplicativo. Você usará a instância FirebaseAuth
como um ponto de entrada para obter essas informações do usuário em uma etapa posterior.MainFragment
está vinculado ao LoginViewModel
. LoginViewModel
é a classe que você incluirá uma variável authenticationState
do tipo FirebaseUserLiveData
. MainFragment
pode então observar o valor desta variável authenticationState
para atualizar a IU de acordo. Nesta etapa, você usará o Console do Firebase para configurar os métodos de autenticação que deseja que seu aplicativo suporte. Para este tutorial, você se concentrará em permitir que os usuários façam login com um endereço de e-mail fornecido por eles ou com sua conta do Google.
Nesta tarefa, você implementará o recurso de login para seus usuários.
MainFragment.kt
. Observe que o objeto authBbutton
não está configurado para tratar com nenhuma entrada do usuário. onViewCreated(),
implemente setOnClickListener
para authButton
para chamar launchSignInFlow()
:MainFragment.kt
binding.authButton.setOnClickListener { launchSignInFlow() }
launchSignInFlow()
em MainFragment.kt
. Atualmente contém um TODO
. launchSignInFlow()
conforme mostrado abaixo. 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 the sign-in intent.
// We listen to the response of this activity with the
// SIGN_IN_REQUEST_CODE.
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
SIGN_IN_REQUEST_CODE
)
}
Isso permite que os usuários se cadastrem e façam login com seu endereço de e-mail ou conta do Google. Se o usuário optar por se registrar com seu endereço de e-mail, a combinação de e-mail e senha que ele criará será exclusiva para seu aplicativo. Isso significa que eles poderão fazer login em seu aplicativo usando essa combinação de endereço de e-mail e senha. No entanto, isso não significa que eles também podem fazer login em qualquer outro aplicativo compatível com o Firebase usando as mesmas credenciais.
MainFragment.kt
, você pode ouvir o resultado do processo de login implementando o método onActivityResult()
, conforme mostrado abaixo. Desde que você iniciou o processo de login com SIGN_IN_REQUEST_CODE
, você também pode ouvir o resultado do processo de login filtrando quando SIGN_IN_REQUEST_CODE
é passado de volta para onActivityResult()
. Comece por ter algumas declarações de registro para saber se o usuário fez login com sucesso: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
// the error code and handle the error.
Log.i(TAG, "Sign in unsuccessful ${response?.error?.errorCode}")
}
}
}
Seu aplicativo agora deve ser capaz de registrar e fazer login de usuários!
Usuário conectado com sucesso $ {seu nome} !
depois de passar pelo fluxo de registro. Nesta tarefa, você implementará a lógica necessária para atualizar a IU com base no estado de autenticação. Quando o usuário está conectado, você pode personalizar sua tela inicial exibindo seu nome. Você também alterará o botão Login para ser um botão Logout quando o usuário estiver conectado.
FirebaseUserLiveData.kt
, que já foi criada para você. A primeira coisa que você precisa fazer é fornecer uma maneira para outras classes no aplicativo saberem quando um usuário efetuou login ou logout. FirebaseAuth
, pode acompanhar as alterações do usuário conectado usando o retorno de chamada FirebaseUser.AuthStateListener
que é implementado para você como parte do FirebaseUI
. Esse retorno de chamada é acionado sempre que um usuário faz login ou sai do seu aplicativo.
FirebaseUserLiveData.kt
define a variável authStateListener
. Você usará esta variável para armazenar o valor do LiveData
. A variável authStateListener
foi criada para que você possa iniciar e parar de ouvir corretamente as alterações no estado de autenticação com base no estado de seu aplicativo. Por exemplo, se o usuário colocar o aplicativo em segundo plano, ele deve parar de ouvir as alterações de estado de autenticação para evitar possíveis vazamentos de memória.authStateListener
para que o valor de seu FirebaseUserLiveData
corresponda ao usuário Firebase atual. FirebaseUserLiveData.kt
private val authStateListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
value = firebaseAuth.currentUser
}
LoginViewModel.kt
.LoginViewModel.kt
, crie uma variável authenticationState
baseada no objeto FirebaseUserLiveData
que você acabou de implementar. Ao criar esta variável authenticationState
, outras classes agora podem consultar se um usuário está conectado ou não por meio do LoginViewModel
.LoginViewModel.kt
val authenticationState = FirebaseUserLiveData().map { user ->
if (user != null) {
AuthenticationState.AUTHENTICATED
} else {
AuthenticationState.UNAUTHENTICATED
}
}
MainFragment.kt.
MainFragment.kt
observeAuthenticationState()
, você pode usar a variável authenticationState
que acabou de adicionar em LoginViewModel
e altere a IU de acordo. Se houver um usuário conectado, authButton
deve exibir 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()
fornecida em MainFragment
.MainFragment.kt
// TODO 2. If the user is logged in...
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
authenticationState
for qualquer coisa diferente de LoginViewModel.AuthenticationState.AUTHENTICATED
), authButton
deve exibir Login e inicie a tela de login quando clicado. Também não deve haver personalização da mensagem exibida.MainFragment.kt
// TODO 3. Lastly, if there is no logged-in user...
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener { launchSignInFlow() }
binding.welcomeText.text = factToDisplay
Com todas as etapas concluídas, seu método observeAuthenticationState()
final deve ser semelhante ao código abaixo.
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()
}
}
}
})
}
Nesta tarefa, você implementará o recurso de logout.
Como o aplicativo permite que os usuários façam login, ele também deve fornecer a eles uma maneira de fazer o logout. Aqui está um exemplo de como desconectar um usuário com apenas uma linha de código:
AuthUI.getInstance().signOut(requireContext())
MainFragment.kt
.MainFragment.kt
observeAuthenticationState()
, adicione a lógica de logout para que o authButton
funcione corretamente quando houver um usuário conectado. O resultado final do método se parece com o código abaixo.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()
}
}
}
})
}
Você pode encontrar a versão final do aplicativo concluído no branch master do seguinte repositório: https://github.com/googletutoriais/android-kotlin-login.
Neste tutorial, você aprendeu:
FirebaseUI
e especificando como você deseja permitir que seus usuários façam login. Observe que qualquer conta que um usuário cria em seu aplicativo é específica apenas para seu aplicativo e não é compartilhada com todos os aplicativos que utilizam o Firebase para a funcionalidade de login.LiveData
.Este tutorial abordou os fundamentos de como oferecer suporte ao login para um aplicativo Android.
Neste tutorial, você permitiu que os usuários se registrassem e fizessem login com seus endereços de e-mail. No entanto, com a biblioteca FirebaseUI
, você também pode oferecer suporte a outros métodos de autenticação, como fazer login com um número de telefone. Para saber mais sobre os recursos da biblioteca FirebaseUI e como utilizar outras funcionalidades que ela oferece, verifique os seguintes recursos:
Para obter mais informações sobre as práticas recomendadas de login, verifique estes outros recursos:
Codelabs:
Documentação do desenvolvedor Android:
Vídeos:
Para obter links para outros tutoriais neste curso, consulte a página inicial de tutoriais do Android avançado em Kotlin.