Dopo l'accesso, sottoscrivo alcuni ref di firebase e successivamente logout (FirebaseAuth.logout). Una volta effettuato il logout, ricevo un avviso Firebase nella console: "Eccezione è stata generata dal callback dell'utente. Errore: permission_denied at ...." e questa diventa un'eccezione effettiva. Mentre mi aspetto di vedere questo comportamento, quali sono le migliori pratiche per la registrazione di un utente in modo da non vedere questo avviso/eccezione?Angularfire2: eccezione e best practice di logout
risposta
Ho avuto lo stesso problema. Attraverso la seguente fonte, ho trovato una soluzione finora, di cui non sono ancora soddisfatto. Source 1
Il problema sta nel fatto che esiste ancora una sottoscrizione aperta, non cancellata (connessione a Firebase) da qualche parte nel codice.
Per esempio ho fatto
this.name_sub = this.af.database.object("https://stackoverflow.com/users/" + user.uid + "/name")
.subscribe(data => {
this.globals.user.name = data.$value;
}
);
Che è tutto bene, fino al punto che si sta invocando this.af.auth.logout();
. Se hai le impostazioni di Firebase Security corrette, Firebase genererà un errore, perché non hai più effettuato l'accesso con l'utente: ora sei anonimo, chi dovrebbe essere bloccato all'interno di uno spazio utente. E poiché la sottoscrizione di cui sopra è ancora attiva, Firebase ti dice che non hai accesso con l'anonimo allo spazio utente di destinazione.
Pertanto, gli abbonamenti devono essere chiusi. Un modo per farlo è aggiungere
ngOnDestroy(){
this.name_sub.unsubscribe();
}
da qualche parte nel componente. Questo chiuderebbe il tuo abbonamento quando il tuo component is destroyed. Purtroppo questo non è possibile per me, perché sto facendo il logout in un altro componente. Il modo in cui lo sto facendo ora sta chiudendo l'abbonamento, subito dopo aver ricevuto un valore.
this.name_sub = this.af.database.object("https://stackoverflow.com/users/" + user.uid + "/name")
.subscribe(data => {
this.globals.user.name = data.$value;
this.name_sub.unsubscribe(); // <-- important part
}
);
Per me, questo è super contro-intuitivo. Penso che abbiamo bisogno di un modo per ricevere valori (s) senza la sottoscrizione permanente al canale dati e senza importare moduli aggiuntivi.
Questa è la risposta corretta; tutti gli abbonamenti devono essere annullati prima di disconnettersi. Generalmente questo è fatto in ngOnDestroy come indicato da Niklas, ed è comunque la migliore pratica per evitare perdite di memoria –
c'è un modo per annullare l'iscrizione di tutto prima di disconnettersi? trovo molto noioso trovare tutti gli abbonamenti ed è anche molto facile da dimenticare in futuro. – alltej
E 'brutto, ma funziona:
signOut(): void {
this.router.navigate(['/app').then(() => {
firebase.database().goOffline() // <=== this eliminates error!
this.afAuth.auth.signOut()
})
}
Si prega di spiegare perché il codice funziona. –
Questa è una buona domanda ed è un peccato che nessuno ha fornito una visione chiara. –