11.16: Un “blog” personale per Android sfruttando Firebase: la creazione dell’account

Condividi su:

L’app dedicata al blog personale è quasi finita, manca ancora qualche dettaglio e una parte fondamentale, la possibilità di permettere a qualsiasi utente di registrarsi e quindi autenticarsi per poter sfruttare il blog. In questo articolo ci dedicheremo proprio a ciò.





Firebase permette di creare account lato client in vari modi, tra cui l’utilizzo di email e password. Noi però non vogliamo limitarci ad acquisire solo queste informazioni da parte degli utenti, ma vogliamo, ad esempio, conoscere anche il loro nome e cognome, o qualsiasi altra informazione.

Tali informazioni dovranno trovare spazio all’interno del database, poiché la sezione Authentication di Firebase è dedicata solo alle credenziali. Dovremo quindi combinare le due cose e far convivere all’interno dello stesso database post e utenti.

Per prima cosa creiamo l’activity dedicata alla registrazione di un nuovo utente: CreateAccountActivity. All’interno del suo layout, oltre ai due campi di testo fondamentali, quello per l’email e l’altro per la password, ne inseriremo altri due, rispettivamente per nome e cognome. Se volete potete inserirne altri. Ovviamente sarà necessario un pulsante per avviare la procedura di registrazione.

Il codice per gestire la registrazione di un utente

Terminato col layout possiamo passare al codice:

public class CreateAccountActivity extends AppCompatActivity {
    private EditText firstNameET;
    private EditText lastNameET;
    private EditText emailET;
    private EditText passwordET;
    private Button createActBT;
    private FirebaseDatabase DB;
    private DatabaseReference DBRef;
    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_account);

        /*
         * Recupero di istanze e riferimenti necessari da Firebase
         */
        DB = FirebaseDatabase.getInstance();
        DBRef = DB.getReference().child("Users");
        mAuth = FirebaseAuth.getInstance();

        /*
         * Istanziazione di tutti i widget presenti all'interno del layout
         */
        firstNameET = (EditText) findViewById(R.id.firstNameAct);
        lastNameET = (EditText) findViewById(R.id.lastNameAct);
        emailET = (EditText) findViewById(R.id.emailAct);
        passwordET = (EditText) findViewById(R.id.passwordAct);
        createActBT = (Button) findViewById(R.id.createAccountAct);

        //Setting del listener sul pulsante  per avviare la procedura di creazione account
        createActBT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createnewAct();
            }
        });
    }

    private void createnewAct() {
        /*
         * Recupero delle informazioni inserite all'interno delle EditText
         */
        final String name = firstNameET.getText().toString().trim();
        final String lName = lastNameET.getText().toString().trim();
        String eMail = emailET.getText().toString().trim();
        String pwd = passwordET.getText().toString().trim();

        //Controllo che tutti i campi siano stati compilati
        if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(lName)
                && !TextUtils.isEmpty(eMail) && !TextUtils.isEmpty(pwd)){
            //Creazione dell'account tramite apposito metodo, con listener sull'esito
            mAuth.createUserWithEmailAndPassword(eMail, pwd).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
                @Override
                public void onSuccess(AuthResult authResult) {
                    if (authResult != null){
                        /*
                         * Se la creazione dell'account ha avuto successo, si memorizzano tutti i
                         * dati dell'utente all'interno del database e si direziona l'utente
                         * verso l'activity con la lista di post
                         */
                        String userID = mAuth.getCurrentUser().getUid();
                        DatabaseReference currentUserDBRef = DBRef.child(userID);
                        currentUserDBRef.child("firstName").setValue(name);
                        currentUserDBRef.child("lastName").setValue(lName);
                        currentUserDBRef.child("avatar").setValue("none");
                        Intent intent = new Intent(CreateAccountActivity.this, PostListActivity.class);
                        //Aggiungiamo un flag all'intent che non fa altro che porre l'activity
                        //destinataria nuovamente in cima allo stack, se già avviata, piuttosto che
                        //avviarne un'altra istanza, terminando contestualmente tutte le altre activity
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(intent);
                    }
                }
            });
        }else{
            //ToDo: codice per gestire il mancato inserimento di tutti i dati
        }
    }
}

Tralasciando tutte le solite operazioni di routine, la parte interessante la troviamo all’interno del metodo “createNewAct()”, richiamato nel momento in cui l’utente clicca sul pulsante per registrare un nuovo account.
Prima di soffermarci su questo, notiamo che come riferimento alla posizione di salvataggio all’interno del database abbiamo recuperato un nodo figlio “Users”. Questo conviverà col nodo “Blog” ed entrambi potranno essere gestiti all’interno dello stesso database, come se fossero due tabelle.

All’interno del metodo “createNewAccount()” recuperiamo in due stringhe il contenuto delle varie EditText. Prima di procedere con qualsiasi altra operazione controlliamo che siano state tutte compilate. Fatto ciò possiamo avviare il metodo di creazione account “createUserWithEmailAndPassword()”, passandovi come parametro le credenziali. A questo colleghiamo un listener, per monitorare l’esito dell’operazione. Fin qui nulla di nuovo.

Grazie al listener “OnSuccessListener” possiamo sapere se l’operazione ha avuto successo, in quel caso verrà invocato il metodo “onSuccess()”. Se l’utente è stato correttamente registrato dobbiamo salvare anche tutti gli altri dati, quindi sarà all’interno di questo metodo che effettueremo tali operazioni.

Attraverso l’istanza di autenticazione (ricordate che una volta che l’utente si è registrato, viene automaticamente autenticato) preleviamo l’ID dell’utente corrente, che è quello appena registrato. Questo ci servirà per ottenere il riferimento ad un nodo figlio del nodo “Users”. Contrassegneremo questo nodo proprio con l’ID utente. All’interno del nodo dedicato all’utente ci saranno tanti nodi quanti sono i dati da salvare, esattamente come abbiamo fatto per i dati dei post.

Mentre per i post del blog ci siamo serviti di una HashMap, qui sfruttiamo varie chiamate al metodo “setValue” sui vari nodi figli contrassegnati ognuno dal dato da memorizzare. Le due procedure sono perfettamente equivalenti, ma questa seconda modalità è più dispendiosa, poiché effettuiamo tanti accessi al database remoto quanti sono i dati da memorizzare, mentre sfruttando la mappa accediamo una sola volta al database.

Una volta memorizzato tutto sul database, possiamo direzionare l’utente verso l’activity di visualizzazione post.
Qui abbiamo una novità, abbiamo sfruttato il metodo “setFlag()” dell’intent per settare un flag su questo: FLAG_ACTIVITY_CLEAR_TOP. Grazie a questo flag, se esiste già un’istanza dell’activity che stiamo richiamando tramite l’intent, questa verrà posta in cima allo stack e terminate tutte le altre activity, altrimenti verrà istanziata ex-novo, sempre terminando tutte le altre. Per come l’abbiamo usato, il risultato è simile alla chiamata al metodo “finish()”, poiché teoricamente abbiamo esclusivamente l’activity di login in backgroud. In altri contesti l’utilizzo di tale flag, piuttosto che terminare esclusivamente l’activity chiamante, risulta più efficiente, dipende ovviamente da ciò che vogliamo ottenere.

Richiamare la nuova activity

Se provate l’app, effettuando il logout e provando a registrare un nuovo utente, non succederà nulla, poiché non abbiamo gestito l’evento click sul pulsante “CREATE NEW ACCOUNT” dell’activity di login (MainActivity). Se ricordate abbiamo sfruttato uno switch, avendo due pulsanti in quella schermata. Sarà sufficiente richiamare il metodo “startActivity()” con l’intent appropriato nel “case” appropriato:

//Gestione del click sul pulsante di creazione nuovo account
case R.id.createAccountBT:
    startActivity(new Intent(MainActivity.this, CreateAccountActivity.class));
    finish();
    break;

Adesso l’app funziona perfettamente, registrando un nuovo utente ed accedendo alla console di Firebase ve lo ritroverete all’interno della sezione “Authentication”. Inoltre, aprendo il database noterete la coesistenza tra dati dei post e dati degli utenti, il tutto gestito con nodi distinti e separati:

Utenti nel database

Visualizzare esclusivamente i post dell’utente autenticato

Con l’app in esecuzione avrete notato anche un’altra cosa, l’utente appena registrato sta visualizzando i post di tutti gli utenti. Se volete che la cosa sia tipo timeline di Twitter, allora nessun problema, ma se vogliamo che ogni utente visualizzi esclusivamente i propri post c’è una piccola modifica da fare.

All’interno di ogni post è memorizzato anche l’ID dell’utente che l’ha salvato, la cosa più semplice da fare è confrontare l’ID utente del post appena prelevato dal database con quello dell’utente corrente. Se sono uguali il post può popolare la lista e quindi essere passato all’adapter della RecyclerView. Avrete capito che la modifica è da fare all’interno del metodo “onChildAdded()” dell’activity PostListActivity. Una volta ottenuto il post dal database, piuttosto che invocare direttamente l’istruzione blogList.add(post);per aggiungerlo alla lista, effettuiamo prima la verifica dell’ID:

//Aggiungiamo il post alla lista se è dell'utente autenticato
if (post.getUserID().equals(mUser.getUid())){
    blogList.add(post);
}

Con questa piccola modifica, ogni utente visualizzerà solo i propri post.



Avrete notato che tra i dati dell’utente abbiamo memorizzato anche una stringa “avatar”, questa conterrà il riferimento ad un’immagine profilo, ma per questo articolo può bastare così, ce ne occuperemo nel prossimo.

Condividi su:

label, , ,

About the author