Questo codelab fa parte del corso Advanced Android in Kotlin. Per ottenere il massimo valore da questo corso, ti consigliamo di seguire i codelab in sequenza, ma non è obbligatorio. Tutti i codelab del corso sono elencati nella pagina di destinazione dei codelab Advanced Android in Kotlin.
Introduzione
Quando crei un'app per Android, il supporto dell'accesso per i tuoi utenti offre molti vantaggi. Consentendo agli utenti di creare un'identità all'interno della tua app, puoi offrire loro più modi per interagire con l'app.
Con gli account personalizzati, gli utenti possono personalizzare la propria esperienza in-app, interagire con altri utenti e trasferire i propri dati se utilizzano l'app su un altro dispositivo (ad esempio web o un nuovo smartphone).
In questo codelab, imparerai le nozioni di base su come supportare l'accesso per la tua app utilizzando la libreria FirebaseUI. Tra le altre cose, la libreria FirebaseUI semplifica la creazione di un flusso di accesso per gli sviluppatori e gestisce il lavoro di gestione degli account utente.
Cosa devi già sapere
- Principi di base per la creazione di un'app per Android
- LiveData e ViewModel
Obiettivi didattici
- Come aggiungere Firebase al tuo progetto
- Come supportare l'accesso per la tua app per Android
- Come osservare lo stato di autenticazione attuale della tua app
- Come disconnettere gli utenti
In questo lab proverai a:
- Utilizza la console Firebase per integrare Firebase nella tua app.
- Implementa la funzionalità di accesso.
- Aggiungi personalizzazioni nell'app per gli utenti che hanno eseguito l'accesso.
- Implementa la disconnessione degli utenti.
Scopri di più su LiveData e ViewModel
Per l'app in questo codelab, devi avere una conoscenza di base di LiveData e ViewModel. Leggi le panoramiche di LiveData e ViewModel se vuoi una breve panoramica di questi concetti.
Puoi anche seguire il corso Developing Android Apps with Kotlin per scoprire gli argomenti fondamentali di Android che incontrerai in questo codelab. Questo corso è disponibile sia come corso Udacity che come corso codelab.
In questo codelab, creerai un'app che mostra curiosità divertenti su Android. Ancora più importante, l'app avrà un pulsante Accedi/Esci. Quando l'utente ha eseguito l'accesso all'app, qualsiasi fatto di Android visualizzato includerà un saluto per l'utente come modo per aggiungere un tocco di personalizzazione.
Scarica l'app di esempio:
... oppure clona il repository GitHub dalla riga di comando utilizzando il seguente comando e passa al branch start
del repository:
$ git clone https://github.com/googlecodelabs/android-kotlin-login
Importante:poiché integrerai l'app per utilizzare Firebase, l'app iniziale richiede una configurazione per poter essere creata ed eseguita. Lo farai nel passaggio successivo del codelab.
Passaggio 1: crea un progetto Firebase
Prima di poter aggiungere Firebase alla tua app per Android, devi creare un progetto Firebase a cui connetterti.
- Nella console Firebase, fai clic su Aggiungi progetto.
- Seleziona o inserisci un nome del progetto. Puoi dare al progetto qualsiasi nome, ma cerca di sceglierne uno pertinente all'app che stai creando.
- Fai clic su Continua.
- Puoi saltare la configurazione di Google Analytics e scegliere l'opzione Non ora.
- Fai clic su Crea progetto per completare la configurazione del progetto Firebase.
Passaggio 2: registra la tua app con Firebase
Ora che hai un progetto Firebase, puoi aggiungervi la tua app per Android.
- Al centro della pagina di riepilogo del progetto della console Firebase, fai clic sull'icona Android per avviare il flusso di lavoro di configurazione.
- Inserisci l'ID applicazione della tua app nel campo Nome pacchetto Android. Assicurati di inserire l'ID utilizzato dalla tua app, poiché non puoi aggiungere o modificare questo valore dopo aver registrato l'app con il tuo progetto Firebase.
- Un ID applicazione a volte viene chiamato nome del pacchetto.
- Trova questo ID applicazione nel file Gradle del modulo (a livello di app), di solito
app/build.gradle
(ID di esempio:com.yourcompany.yourproject
). - Inserisci il certificato SHA-1 per la firma di debug. Puoi generare questa chiave inserendo il seguente comando nel terminale della riga di comando.
keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v -storepass android
- Fai clic su Registra app.
Passaggio 3: aggiungi il file di configurazione Firebase al progetto
Aggiungi il file di configurazione Firebase Android alla tua app:
- Fai clic su Scarica google-services.json per ottenere il file di configurazione di Firebase per Android (
google-services.json
).
- Puoi scaricare di nuovo il file di configurazione Firebase per Android in qualsiasi momento.
- Assicurati che al file di configurazione non vengano aggiunti caratteri aggiuntivi e che il nome sia solo
google-services.json
- Sposta il file di configurazione nella directory del modulo (a livello di app) della tua app.
Passaggio 4: configura il tuo progetto Android per attivare i prodotti Firebase
- Per attivare i prodotti Firebase nella tua app, aggiungi il plug-in google-services ai tuoi file Gradle.
- Nel file Gradle a livello di directory principale (a livello di progetto) (
build.gradle
), aggiungi regole per includere il plug-in dei servizi Google. Verifica di avere anche il repository Maven di 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
// ...
}
}
- Nel file Gradle del modulo (a livello di app, di solito
app/build.gradle
), aggiungi una riga in fondo al file.
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
Passaggio 4: aggiungi la dipendenza Firebase
In questo codelab il motivo principale per l'integrazione di Firebase è avere un modo per creare e gestire gli utenti. Per farlo, devi aggiungere una libreria Firebase che ti consenta di implementare l'accesso.
- Aggiungi la seguente dipendenza nel file
build.gradle (Module:app)
per poter utilizzare l'SDK nella tua app. L'SDKfirebase-auth
consente la gestione degli utenti autenticati della tua applicazione.
app/build.gradle:
implementation 'com.firebaseui:firebase-ui-auth:5.0.0'
- Sincronizza il progetto con i file Gradle per assicurarti che tutte le dipendenze siano disponibili per la tua app. Se non ti viene richiesto, seleziona File > Sync Project with Gradle Files in Android Studio o dalla barra degli strumenti.
Passaggio 5: esegui l'app e ispeziona il codice
- Esegui l'app su un emulatore o un dispositivo fisico per assicurarti che l'ambiente sia configurato correttamente per iniziare lo sviluppo.
Se l'operazione ha esito positivo, nella schermata Home viene visualizzato un aneddoto divertente su Android e un pulsante di accesso nell'angolo in alto a sinistra. Se tocchi il pulsante di accesso, per il momento non succede nulla.
A livello generale, si tratta di un'app con una sola attività e più frammenti. Il MainFragment
contiene tutta l'interfaccia utente che vedi nella schermata seguente. Lavoreremo con LoginFragment
e SettingsFragment
in un codelab successivo.
- Acquisisci familiarità con il codice. In particolare, nota:
FirebaseUserLiveData
è la classe che implementerai per osservare l'utente Firebase corrente associato all'app. Utilizzerai l'istanzaFirebaseAuth
come punto di accesso per ottenere le informazioni dell'utente in un passaggio successivo.MainFragment
è legato aLoginViewModel
.LoginViewModel
è la classe che implementerai per utilizzareFirebaseUserLiveData
per creare una variabileauthenticationState
. Utilizzando questa variabileauthenticationState
,MainFragment
può quindi osservare il valore per aggiornare l'interfaccia utente di conseguenza.
In questo passaggio utilizzerai la console Firebase per configurare i metodi di autenticazione che vuoi che la tua app supporti. Per questo codelab, ti concentrerai sul consentire agli utenti di accedere con un indirizzo email fornito o con il proprio Account Google.
- Vai alla console Firebase. Nota: se ti trovi ancora nel flusso di lavoro Aggiungi Firebase, fai clic sulla X nell'angolo in alto a sinistra per tornare alla console.
- Seleziona il progetto, se non lo hai già fatto.
- Apri il menu di navigazione a sinistra e seleziona Sviluppa > Autenticazione .
- Seleziona la scheda Metodo di accesso nella barra di navigazione in alto.
- Fai clic sulla riga Email/Password.
- Nel popup, attiva/disattiva l'opzione Attivata e fai clic su Salva.
- Allo stesso modo, fai clic sulla riga Google.
- Attiva l'opzione Attivata, inserisci un'email di assistenza per il progetto e fai clic su Salva.
In questa attività implementerai la funzionalità di accesso per i tuoi utenti.
- Apri
MainFragment.kt
. - Nel layout di
MainFragment
, notaauth_button
. Al momento non è configurato per gestire l'input dell'utente. - In
onViewCreated(),
aggiungi unonClickListener
aauth_button
per chiamarelaunchSignInFlow()
.
MainFragment.kt
binding.authButton.setOnClickListener { launchSignInFlow() }
- Cerca il metodo
launchSignInFlow()
inMainFragment.kt
. Al momento contiene unTODO
. - Completa la funzione
launchSignInFlow()
come mostrato di seguito.
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
)
}
Ciò consente agli utenti di registrarsi e accedere con il proprio indirizzo email o Account Google. Se l'utente sceglie di registrarsi con il proprio indirizzo email, la combinazione di email e password che crea è univoca per la tua app. Ciò significa che potrà accedere alla tua app con la combinazione di indirizzo email e password, ma non potrà accedere a qualsiasi altra app supportata da Firebase con le stesse credenziali.
- In
MainFragment.kt
, puoi ascoltare il risultato della procedura di accesso implementando il metodoonActivityResult()
, come mostrato di seguito. Poiché hai avviato la procedura di accesso conSIGN_IN_REQUEST_CODE
, puoi anche ascoltare il risultato della procedura di accesso filtrando i risultati in base al momento in cuiSIGN_IN_REQUEST_CODE
viene restituito aonActivityResult()
. Inizia con alcune istruzioni di log per sapere se l'utente ha eseguito l'accesso correttamente.
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}")
}
}
}
Ora la tua app dovrebbe essere in grado di gestire la registrazione e l'accesso degli utenti.
- Esegui l'app e verifica che toccando il pulsante Accedi venga visualizzata la schermata di accesso.
- Ora puoi accedere con il tuo indirizzo email e una password oppure con il tuo Account Google.
- Non ci saranno modifiche all'interfaccia utente dopo l'accesso (implementerai l'aggiornamento dell'interfaccia utente nel passaggio successivo), ma se tutto funziona correttamente, dovresti visualizzare il messaggio di log
Successfully signed in user ${your name}!
dopo aver completato il flusso di registrazione. - Puoi anche accedere alla console Firebase e andare a Sviluppa > Autenticazione > Utenti per verificare che l'app ora abbia un utente registrato.
- Tieni presente che quando gli utenti creano un account per la tua app, questo account è collegato specificamente solo alla tua app e non a qualsiasi app che utilizza Firebase per la funzionalità di accesso.
In questa attività implementerai l'aggiornamento della UI in base allo stato di autenticazione. Quando l'utente ha eseguito l'accesso, puoi personalizzare la schermata Home visualizzando il suo nome. Aggiornerai anche il pulsante Accedi in modo che diventi un pulsante Esci quando l'utente ha eseguito l'accesso.
- Apri il corso
FirebaseUserLiveData.kt
, che è già stato creato per te. La prima cosa da fare è fornire un modo per far sapere alle altre classi dell'app quando un utente ha eseguito l'accesso o la disconnessione. Tuttavia, la classe non fa ancora nulla perché il valore diLiveData
non viene aggiornato. - Poiché utilizzi la libreria
FirebaseAuth
, puoi ascoltare le modifiche all'utente che ha eseguito l'accesso con il callbackFirebaseUser.AuthStateListener
implementato per te nell'ambito della libreria FirebaseUI. Questo callback viene attivato ogni volta che un utente esegue l'accesso o la disconnessione dalla tua app. - Tieni presente che
FirebaseUserLiveData.kt
definisce la variabileauthStateListener
. Utilizzerai questa variabile per memorizzare il valore diLiveData
. La variabileauthStateListener
è stata creata per consentirti di avviare e interrompere correttamente l'ascolto delle modifiche nello stato di autenticazione in base allo stato della tua applicazione. Ad esempio, se l'utente mette l'app in background, l'app deve smettere di ascoltare le modifiche dello stato di autenticazione per evitare potenziali perdite di memoria. - Aggiorna
authStateListener
in modo che il valore diFirebaseUserLiveData
corrisponda all'utente Firebase corrente.
FirebaseUserLiveData.kt
private val authStateListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
value = firebaseAuth.currentUser
}
- Apri
LoginViewModel.kt
. - In
LoginViewModel.kt
, crea una variabileauthenticationState
basata sull'oggettoFirebaseUserLiveData
che hai appena implementato. Con la creazione di questa variabileauthenticationState
, le altre classi possono ora eseguire query per verificare se l'utente ha eseguito l'accesso o meno tramiteLoginViewModel
.
LoginViewModel.kt
val authenticationState = FirebaseUserLiveData().map { user ->
if (user != null) {
AuthenticationState.AUTHENTICATED
} else {
AuthenticationState.UNAUTHENTICATED
}
}
- Apri
MainFragment.kt.
- Nel file
observeAuthenticationState()
diMainFragment.kt
puoi utilizzare la variabileauthenticationState
che hai appena aggiunto inLoginViewModel
e modificare di conseguenza l'interfaccia utente. Se è presente un utente che ha eseguito l'accesso,authButton
deve mostrare Disconnessione.
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.
}
}
})
}
- Se l'utente ha eseguito l'accesso, puoi anche personalizzare il messaggio di benvenuto che vede utilizzando la funzione
getFactWithPersonalization()
fornita inMainFragment
.
MainFragment.kt
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
- Infine, se non è presente alcun utente connesso (quando
authenticationState
è diverso daLoginViewModel.AuthenticationState.AUTHENTICATED
),auth_button
deve visualizzare Accedi e avviare la schermata di accesso quando viene selezionato. Inoltre, non deve essere presente alcuna personalizzazione del messaggio visualizzato.
MainFragment.kt
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener { launchSignInFlow() }
binding.welcomeText.text = factToDisplay
Una volta completati tutti i passaggi, il metodo observeAuthenticationState()
finale dovrebbe essere simile al codice riportato di seguito.
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()
}
}
}
})
}
- Esegui l'app. L'interfaccia utente deve aggiornarsi a seconda che un utente abbia eseguito l'accesso o meno. Se tutto funziona correttamente e hai eseguito l'accesso, la schermata Home dovrebbe ora salutarti con il tuo nome, oltre a mostrare una curiosità su Android. Ora il pulsante Accedi dovrebbe mostrare anche Esci.
In questa attività implementerai la funzionalità di disconnessione.
Poiché l'app consente agli utenti di accedere, deve anche fornire loro un modo per uscire. Ecco un esempio di come disconnettere un utente con una sola riga di codice:
AuthUI.getInstance().signOut(requireContext())
- Apri
MainFragment.kt
. - In
MainFragment.kt
'sobserveAuthenticationState()
, aggiungi la logica di disconnessione in modo cheauth_button
funzioni correttamente quando è presente un utente connesso. Il risultato finale del metodo è simile al codice riportato di seguito.
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()
}
}
}
})
}
- Esegui l'app.
- Tocca il pulsante Esci e verifica che l'utente abbia eseguito la disconnessione e che lo stato del pulsante cambi in Accedi.
Puoi trovare la versione finale dell'app completata qui https://github.com/googlecodelabs/android-kotlin-login.
In questo codelab hai imparato:
- Come aggiungere Firebase al tuo progetto aggiungendo le dipendenze necessarie nel file gradle e configurando il progetto nella console Firebase.
- Come implementare l'accesso per la tua app utilizzando la libreria FirebaseUI e specificando in che modo vuoi consentire agli utenti di accedere. Tieni presente che qualsiasi account creato da un utente nella tua app è specifico solo per la tua app e non viene condiviso con tutte le app che utilizzano Firebase per la funzionalità di accesso.
- Come osservare lo stato di autenticazione attuale della tua app utilizzando
LiveData
. - Come disconnettere gli utenti.
Questo codelab ha trattato le nozioni di base su come supportare l'accesso per un'app per Android.
In questo codelab hai consentito agli utenti di registrarsi e accedere con il proprio indirizzo email. Tuttavia, con la libreria FirebaseUI puoi supportare anche altri metodi di autenticazione, ad esempio l'accesso con un numero di telefono. Per saperne di più sulle funzionalità della libreria FirebaseUI e su come utilizzare le altre funzionalità che offre, consulta le seguenti risorse:
- Documentazione sull'autenticazione di FirebaseUI
- Demo di autenticazione FirebaseUI e codice di esempio
Per saperne di più sulle best practice relative all'accesso, consulta queste altre risorse:
Codelab:
Documentazione per sviluppatori Android:
Video:
Per i link ad altri codelab di questo corso, consulta la pagina di destinazione dei codelab Advanced Android in Kotlin.