2016-06-02 25 views
7

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

+0

Questa è una buona domanda ed è un peccato che nessuno ha fornito una visione chiara. –

risposta

8

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.

+0

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 –

+0

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

0

E 'brutto, ma funziona:

signOut(): void { 
    this.router.navigate(['/app').then(() => { 
     firebase.database().goOffline()  // <=== this eliminates error! 
     this.afAuth.auth.signOut() 
    }) 
    } 
+1

Si prega di spiegare perché il codice funziona. –