Questo codelab fa parte del corso Advanced Android in Kotlin. Otterrai il massimo valore da questo corso se lavori in sequenza nei codelab, ma non è obbligatorio. Tutti i codelab del corso sono elencati nella pagina di destinazione avanzata per i codelab di Android in Kotlin.
Introduzione
Lo sviluppo dell'app per Android può comportare diversi vantaggi. Se consenti agli utenti di creare un'identità all'interno della tua app, puoi offrire loro altri modi per interagire con l'app.
Con gli account personalizzati gli utenti possono personalizzare la propria esperienza in-app, interagire con altri utenti e mantenere i propri dati e trasferirli se utilizzano l'app su un altro dispositivo (ad esempio su Web o su un nuovo telefono).
In questo codelab, imparerai le nozioni di base su come supportare l'accesso alla tua app utilizzando la libreria Firebase. Tra le altre cose, la libreria FirebaseUI rende facile agli sviluppatori che vogliono creare un flusso di accesso e gestisce il lavoro della gestione degli account utente al posto tuo.
Informazioni importanti
- Nozioni di base sulla creazione di un'app Android
- LiveData e ViewModel
Obiettivi didattici
- Come aggiungere Firebase al tuo progetto
- Come supportare l'accesso alla tua app Android
- Come controllare lo stato di autenticazione attuale dell'app
- Come disconnettere gli utenti
In questo lab proverai a:
- Utilizzare la Console Firebase per integrare Firebase nella tua app.
- Implementare la funzionalità di accesso.
- Aggiungi personalizzazioni nell'app per gli utenti che hanno eseguito l'accesso.
- Implementare la disconnessione degli utenti.
Scopri di più su LiveData e ViewModel
Per l'app in questo codelab, è necessaria una conoscenza di base di LiveData e Viewmodel. Leggi le panoramiche LiveData e Viewmodel se vuoi una breve panoramica di questi concetti.
Puoi anche seguire il corso Sviluppo di app Android con Kotlin per scoprire gli argomenti fondamentali di Android che incontrerai nell'ambito di questo codelab. Il corso è disponibile sia come corso su Udacity sia come corso su codelab.
In questo codelab, creerai un'app che mostra curiosità su Android. Aspetto ancora più importante: l'app ha un pulsante Accedi/Esci. Quando l'utente ha eseguito l'accesso all'app, qualsiasi informazione mostrata su Android mostrerà un saluto all'utente per aggiungere un tocco di personalizzazione.
Per scaricare l'app di esempio, puoi:
... oppure clona il repository GitHub dalla riga di comando utilizzando il comando seguente e passa al ramo start
del repository:
$ git clone https://github.com/googlecodelabs/android-kotlin-login
Importante: dato che integrerai l'app per utilizzare Firebase, l'app iniziale dovrà essere configurata in modo da poter essere creata ed eseguita. Dovrai farlo nel passaggio successivo del codelab.
Passaggio 1: crea un progetto Firebase
Prima di poter aggiungere Firebase alla tua app Android, devi creare un progetto Firebase per connetterti all'app.
- Nella Console Firebase, fai clic su Aggiungi progetto.
- Seleziona o inserisci un Nome progetto. Puoi assegnare un nome al progetto qualsiasi, ma cerca di scegliere un nome 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 creato un progetto Firebase, puoi aggiungervi l'app per Android.
- Al centro della pagina Panoramica 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 del pacchetto Android. Assicurati di inserire l'ID utilizzato dalla tua app, poiché non potrai aggiungere o modificare questo valore dopo aver registrato l'app con il tuo progetto Firebase.
- Un ID applicazione è a volte indicato come nome del pacchetto.
- Trova questo ID applicazione nel file Gradle del tuo modulo (a livello di app), in genere
app/build.gradle
(ID 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 di Firebase Android alla tua app:
- Fai clic su Scarica google-services.json per ottenere il file di configurazione di Firebase Android (
google-services.json
).
- Puoi scaricare di nuovo il file di configurazione Android di Firebase in qualsiasi momento.
- Assicurati che al file di configurazione non siano aggiunti caratteri aggiuntivi e che abbia il nome
google-services.json
- Sposta il file di configurazione nella directory del modulo (a livello di app) dell'app.
Passaggio 4: configura il 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 progetto (
build.gradle
) a livello di progetto, aggiungi le regole per includere il plug-in 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 tuo modulo (a livello di app, in genere
app/build.gradle
), aggiungi una riga alla fine del 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 è la creazione e la gestione di utenti. Per farlo, devi aggiungere una libreria Firebase che ti consenta di implementare l'accesso.
- Aggiungi la seguente dipendenza al file
build.gradle (Module:app)
in modo da 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 tuo progetto con file gradle per assicurarti che tutte le dipendenze siano disponibili per la tua app. Se non richiesto, scegli File > Sync Project with Gradle Files in Android Studio o dalla barra degli strumenti.
Passaggio 5: esegui l'app e analizza il codice
- Esegui l'app su un emulatore o un dispositivo fisico per assicurarti che il tuo ambiente sia configurato correttamente per iniziare lo sviluppo.
In caso di esito positivo, dovresti visualizzare la schermata Home con una curiosità su Android e un pulsante di accesso nell'angolo in alto a sinistra. Non devi fare nulla se tocchi il pulsante di accesso.
In linea generale, si tratta di un'unica app per attività con più frammenti. L'elemento MainFragment
contiene tutta l'UI che vedi nella schermata di seguito. Lavorerai con LoginFragment
e SettingsFragment
in un codelab di follow-up.
- Familiarizza con il codice. In particolare, tieni presente quanto segue:
FirebaseUserLiveData
è la classe che implementerai per osservare l'utente Firebase attuale associato all'app. Utilizzerai l'istanzaFirebaseAuth
come punto di contatto per recuperare queste 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 vengano supportati dalla tua app. Per questo codelab, ti concentrerai sulla possibilità di consentire agli utenti di accedere con un indirizzo email fornito o con il proprio Account Google.
- Vai alla Console Firebase. (Nota: se sei ancora nel flusso di lavoro di Aggiungi Firebase, fai clic sulla X nell'angolo in alto a sinistra per tornare alla console.
- Seleziona il progetto, se non è già presente.
- Apri il menu di navigazione a sinistra e seleziona Sviluppo > Autenticazione.
- Seleziona la scheda Metodo di accesso nella barra di navigazione in alto.
- Fai clic sulla riga Email/password.
- Nella finestra popup, attiva l'opzione Attiva e fai clic su Salva.
- Allo stesso modo, fai clic sulla riga Google.
- Attiva l'opzione Abilitata, inserisci un indirizzo email dell'assistenza e fai clic su Salva.
In questa attività implementerai la funzionalità di accesso per gli utenti.
- Apri
MainFragment.kt
. - Nel layout di
MainFragment
, nota ilauth_button
. Attualmente non è configurato per gestire gli input degli utenti. - In
onViewCreated(),
aggiungi unonClickListener
aauth_button
per chiamarelaunchSignInFlow()
.
Fragment.kt principale
binding.authButton.setOnClickListener { launchSignInFlow() }
- Cerca il metodo
launchSignInFlow()
inMainFragment.kt
. Al momento contiene un elementoTODO
. - Completa la funzione
launchSignInFlow()
come mostrato di seguito.
Fragment.kt principale
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
)
}
Questa operazione 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 indirizzo email e password creata è 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. Da quando hai iniziato la procedura di accesso conSIGN_IN_REQUEST_CODE
, puoi anche ascoltare il risultato della procedura di accesso filtrando per quandoSIGN_IN_REQUEST_CODE
viene restituito aonActivityResult()
. Inizia con alcune istruzioni di log per capire se l'utente ha eseguito l'accesso.
Fragment.kt principale
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 il tocco sul pulsante Accedi mostri la schermata di accesso.
- Ora puoi accedere con il tuo indirizzo email e una password o con il tuo Account Google.
- Una volta eseguito l'accesso, l'interfaccia utente non verrà modificata dopo aver eseguito l'aggiornamento (nel passaggio successivo), ma se tutto funziona correttamente, dopo il completamento del flusso di registrazione dovrebbe essere visualizzato il messaggio di log
Successfully signed in user ${your name}!
. - Puoi anche accedere alla Console Firebase e selezionare Sviluppo > 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 esclusivamente all'app e non a qualsiasi app che utilizza Firebase per la funzionalità di accesso.
In questa attività, implementerai l'aggiornamento dell'interfaccia utente in base allo stato di autenticazione. Se l'utente ha eseguito l'accesso, puoi personalizzare la schermata Home visualizzandone il nome. Inoltre, il pulsante Login (Accesso) diventerà Logout (Accesso) quando l'utente avrà eseguito l'accesso.
- Apri il corso
FirebaseUserLiveData.kt
, che è già stato creato per te. La prima cosa da fare è fornire agli altri corsi nell'app un modo per sapere quando un utente ha eseguito l'accesso o è uscito. Tuttavia, il corso non fa ancora nulla perché il valore diLiveData
non viene aggiornato. - Poiché utilizzi la libreria
FirebaseAuth
, puoi ascoltare le modifiche apportate all'utente che ha eseguito l'accesso con il callbackFirebaseUser.AuthStateListener
implementato automaticamente per te all'interno della libreria FirebaseUI. Questo callback viene attivato ogni volta che un utente accede o esce dalla tua app. - Tieni presente che
FirebaseUserLiveData.kt
definisce la variabileauthStateListener
. Utilizzerai questa variabile per memorizzare il valore diLiveData
. La variabileauthStateListener
è stata creata, in modo da poter avviare e interrompere correttamente l'ascolto delle modifiche in stato di autenticazione in base allo stato dell'applicazione. Ad esempio, se l'utente inserisce l'app in background, l'app non deve più ascoltare le modifiche dello stato di autenticazione per evitare potenziali perdite di memoria. - Aggiorna
authStateListener
in modo che il valore della variabileFirebaseUserLiveData
corrisponda all'attuale utente Firebase.
FirebaseUserLiveData.kt
private val authStateListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
value = firebaseAuth.currentUser
}
- Apri
LoginViewModel.kt
. - In
LoginViewModel.kt
, crea una variabileauthenticationState
basata sull'oggettoFirebaseUserLiveData
appena implementato. Creando questa variabileauthenticationState
, altre classi possono ora verificare se l'utente ha effettuato l'accesso o meno tramiteLoginViewModel
.
LoginViewModel.kt
val authenticationState = FirebaseUserLiveData().map { user ->
if (user != null) {
AuthenticationState.AUTHENTICATED
} else {
AuthenticationState.UNAUTHENTICATED
}
}
- Apri
MainFragment.kt.
- In
observeAuthenticationState()
diMainFragment.kt
puoi utilizzare la variabileauthenticationState
appena aggiunta inLoginViewModel
e modificare l'interfaccia utente di conseguenza. Se è presente un utente che ha eseguito l'accesso,authButton
dovrebbe visualizzare Logout.
Fragment.kt principale
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 utilizzando la funzione
getFactWithPersonalization()
fornita inMainFragment
.
Fragment.kt principale
binding.welcomeText.text = getFactWithPersonalization(factToDisplay)
- Infine, se non è presente alcun utente che ha eseguito l'accesso (quando
authenticationState
è diverso daLoginViewModel.AuthenticationState.AUTHENTICATED
),auth_button
dovrebbe visualizzare Accesso e avviare la schermata di accesso quando viene fatto clic. Inoltre, il messaggio non deve essere personalizzato.
Fragment.kt principale
binding.authButton.text = getString(R.string.login_button_text)
binding.authButton.setOnClickListener { launchSignInFlow() }
binding.welcomeText.text = factToDisplay
Dopo aver completato tutti i passaggi, il metodo observeAuthenticationState()
finale dovrebbe essere simile al codice riportato di seguito.
Fragment.kt principale
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 la tua app. L'interfaccia utente dovrebbe aggiornarsi in base al fatto che un utente abbia eseguito o meno l'accesso. Se tutto funziona correttamente e hai effettuato l'accesso, nella schermata Home dovresti vedere il tuo nome, oltre a visualizzare un fatto Android. Anche il pulsante Login (Accedi) dovrebbe essere visualizzato, Logout.
In questa attività implementerai la funzionalità di disconnessione.
L'app consente agli utenti di eseguire l'accesso e dovrebbe fornire loro anche 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
. - Nella
observeAuthenticationState()
diMainFragment.kt
, aggiungi la logica di disconnessione in modo cheauth_button
funzioni correttamente quando è presente un utente che ha eseguito l'accesso. Il risultato finale del metodo sembra simile al seguente codice.
Fragment.kt principale
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 sia disconnesso; lo stato del pulsante cambierà in Accedi.
La versione finale dell'app completata è disponibile qui https://github.com/googlecodelabs/android-kotlin-login.
In questo codelab, hai imparato:
- Come aggiungere Firebase al progetto aggiungendo le dipendenze necessarie nel file Gradle e configurando il progetto nella Console Firebase.
- Come implementare l'accesso alla tua app utilizzando la libreria FirebaseUI e specificando come consentire agli utenti di accedere. Tieni presente che gli account creati dagli utenti nella tua app sono specifici per la tua app e non condivisi con tutte le app che utilizzano Firebase per la funzionalità di accesso.
- Come controllare lo stato di autenticazione attuale della tua app con
LiveData
. - Come disconnettere gli utenti.
Questo codelab ha trattato le nozioni di base su come supportare l'accesso per un'app Android.
In questo codelab hai consentito agli utenti di registrarsi e accedere con il loro indirizzo email. Tuttavia, con la libreria FirebaseUI puoi anche supportare 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 altre funzionalità che offre, consulta le seguenti risorse:
- Documentazione sull'autenticazione di FirebaseUI
- Demo e codice di esempio dell'autenticazione di Firebase
Per ulteriori informazioni sulle best practice per l'accesso, consulta queste altre risorse:
Codelab:
Documentazione per gli sviluppatori Android:
Video:
Per i link ad altri codelab in questo corso, consulta la pagina di destinazione Advanced Android in Kotlin.