Posso fare Firebase utilizzare un process di login per il nome utente?

Vorrei creare un sistema che permette di accedere a un nome utente. Questo process richiede quanto segue:

  1. L'utente deve registrarsi con un'email / password
  2. L'utente può impostare un nome utente univoco
  3. L'utente può eseguire l'accesso con e-mail o nome utente
  4. L'utente può recuperare la propria password tramite posta elettronica o username
  5. La funzionalità deve funzionare su un database di abilitazione persistente

Questa domanda è stata risolta in precedenza, ma distriggers la funzionalità per l'utente di utilizzare il recupero della password. Inoltre non hanno affrontato la sensibilità dei casi, una persona potrebbe registrarsi come "scooby" e un altro come "Scooby".

  • android ottiene la posizione dal miglior fornitore disponibile
  • Programmazione Android - risoluzione dello schermo
  • Divisore ListView non mostrando
  • Webview di Android - Rileva il nome dell'intestazione mentre scorre l'utente
  • Come utilizzare correttamente il vector compatibile all'indietro Disegnabile con l'ultima libreria di supporto Android?
  • android: Posso usare una class diversa per il figlio diverso di viewflipper
  • Come distriggersre un button Android?
  • aggiungere dynamicmente il layout nel metodo getview di adattatore in android
  • SQLite: come limitare il numero di righe in base al timestamp?
  • La row di command è troppo lunga nell'attività di build dexDebugTest
  • Android: Prendere il controllo completo del telefono (modalità chiosco), è ansible? Come?
  • Come ordinare i risultati di CursorLoader?
  • One Solution collect form web for “Posso fare Firebase utilizzare un process di login per il nome utente?”

    Dopo molteplici iterazioni di sviluppo ho trovato il seguente disegno per affrontare questo problema. Posso submit i miei frammenti di codice in Swift, ma in genere saranno facilmente traducibili direttamente in Android.


    1. Creare un process di logging di Firebase per posta elettronica / password.

    Ciò è richiesto come la spina dorsale dell'esperienza di accesso dell'utente. Questo può essere implementato completamente dalla documentazione Firebase API fornita qui


    1. Ricall l'utente per inserire il proprio nome utente

    La voce di nome utente dovrebbe essere completata alla logging, suggerirei un field aggiuntivo nel stream di logging. Raccommand anche di controllare se l'utente ha un nome utente each volta che si accede. Se non lo fanno, visualizza un'interface di SetUsername che richiede di impostare un nome utente prima di avanzare ulteriormente nell'interface utente. Un utente potrebbe non avere un nome utente per alcune ragioni; potrebbe essere revocato per essere maleducato o riservato, o che potrebbero essere stati registrati prima che il nome utente richiesto alla logging.

    Assicurarsi che se utilizzi una build di Firebase abilitata alla persistenza che utilizzi le transactions Firebase . Le transactions sono necessarie, altrimenti l'applicazione può fare ipotesi sui dati nella tabella degli utenti, anche se un utente potrebbe essere stato impostato per un utente solo pochi secondi prima.

    Vorrei anche consigliare l'applicazione del nome utente per essere quasi alfanumbersco (mi permetto di qualche punteggiatura innocua). In Swift posso get questo con il seguente codice:

    static var invalidCharacters:NSCharacterSet { let chars = NSMutableCharacterSet.alphanumberscCharacterSet() // I add _ - and . to the valid characters. chars.addCharactersInString("_-.") return chars.invertedSet } if username.rangeOfCharacterFromSet(invalidCharacters) != nil { // The username is valid } 

    1. Salvataggio dei dati utente

    Il prossimo passo importnte è sapere come salvare i dati dell'utente in modo che possiamo accedervi in ​​futuro. Di seguito troverai uno screenshot del modo in cui archivii i miei dati utente: Gerarchia degli utenti Alcune cose da notare:

    • I nomi utente vengono memorizzati due volte, una volta nei usernames e nuovamente nel details/[uid]/username . Raccommand questo perché ti consente di essere sensibili ai casi di maiuscolo con i nomi utente (vedi il punto successivo) e ti consente anche di conoscere il riferimento esatto del database per controllare un nome utente ( usernames/scooby ) piuttosto che wherer interrogare o controllare i figli di details per trovare un nome utente che corrisponde (che diventerebbe più complicato quando si deve fattorizzare la sensibilità dei casi)
    • il riferimento dei usernames viene memorizzato in minuscolo. Quando controlla i valori in questo riferimento o quando salvo a questo riferimento, assicuro che salvo solo i dati in minuscolo. Ciò significa che se qualcuno vuole verificare se il nome utente "scoobY" esiste, non riesce perché in minuscolo è lo stesso nome utente dell'utente esistente "Scooby".
    • Il field details/[uid]/username contiene i capitoli. Ciò consente di visualizzare il nome utente in caso di preferenza per l'utente, piuttosto che eseguire una parola minuscola o una parola capitalizzata, l'utente può specificare il proprio nome come "NASA Fan" e non essere convertito in "Nasa Fan", impedendo altresì chiunque altro da registrare il nome utente "NASA FAN" (o qualsiasi altra iterazione di casi)
    • Le email vengono memorizzate nei dettagli utente. Questo potrebbe sembrare peculiare perché è ansible recuperare l'email dell'utente corrente tramite Firebase.auth().currentUser.email? . Il motivo per cui è necessario è perché abbiamo bisogno di riferimenti alle e-mail prima di accedere come utente.

    1. Accesso con e-mail o nome utente

    Per far funzionare senza problemi, è necessario incorporare alcuni controlli all'account di accesso.

    Dal momento che ho distriggersto il carattere @ nei nomi utente, posso supporre che una richiesta di login contenente un @ sia una richiesta di posta elettronica. Queste richieste vengono elaborate normalmente, usando il FIRAuth.auth().signInWithEmail(email, password, completion) di Firebase FIRAuth.auth().signInWithEmail(email, password, completion) .

    Per tutte le altre richieste, assumiamo che sia una richiesta di nome utente. Nota: il cast in minuscolo.

     let ref = FIRDatabase.database().reference() let usernameRef = ref.child("users/usernames/\(username.lowercaseString)") 

    Quando si esegue questo recupero, è necessario considerare se è abilitata la persistenza e se è ansible che un nome utente venga revocato. Se un nome utente potrebbe essere revocato e hai abilitato la persistenza, si desidera assicurarsi di recuperare il valore di un nome utente all'interno di un block di transactions per assicurarsi di non get un valore memorizzato nella cache.

    Quando questo recupero ha successo, otterrai il valore dal username[username] , che è l'utente dell'utente. Con questo valore è ansible eseguire un recupero sul valore di posta elettronica dell'utente:

     let ref = FIRDatabase.database().reference() let usernameRef = ref.child("users/details/[uid]/email") 

    Una volta che questa richiesta riesce, è ansible eseguire l'accesso standard di posta elettronica Firebase con la string di email appena recuperata.

    Gli stessi methods di recupero possono essere utilizzati per recuperare un messaggio di posta elettronica da un nome utente per consentire il recupero della password.

    Alcuni punti per essere prudenti per le funzionalità avanzate: – Se si consente all'utente di aggiornare la propria posta elettronica utilizzando FIRUserProfileChangeRequest , assicurarsi di aggiornarlo sia sull'authentication e sul field di details[uid]email , altrimenti si romperà la funzionalità di login per il nome utente – È ansible ridurre significativamente il codice necessario per gestire tutti i diversi casi di guasto nei methods di recupero utilizzando blocchi di successo e di guasto. Ecco un esempio del mio metodo di posta elettronica:

     static func getEmail(username:String, success:(email:String) -> Void, failure:(error:String!) -> Void) { let usernameRef = FIRDatabase.database().reference().child("users/usernames/\(username.lowercaseString)") usernameRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in if let userId = snapshot.value as? String { let emailRef = FIRDatabase.database().reference().child("users/details/\(userId)/email") emailRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in if let email = snapshot.value as? String { success(email: email) } else { failure(error: "No email found for username '\(username)'.") } }) { (error) in failure(error: "Email could not be found.") } } else { failure(error: "No account found with username '\(username)'.") } }) { (error) in failure(error: "Username could not be found.") } } 

    Questa implementazione di block di successo / guasto consente che il codice che chiami nei miei ViewControllers sia molto più pulito. Å login chiama il seguente metodo:

     if fieldText.containsString("@") { loginWithEmail(fieldText) } else { // Attempt to get email for username. LoginHelper.getEmail(fieldText, success: { (email) in self.loginWithEmail(email) }, failure: { error in HUD.flash(.Error, delay: 0.5) }) } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.