1

Meine Benutzer eine Liste der Helden mögen kann, so habe ich diese Struktur in meinem Feuerbasis Regeln/Daten:Angularfire2: Verschachtelte Observablen auf Auth Änderung und die Erlaubnis verweigert

"user_flags": { 
    "$uid": { 
    ".write": "auth.uid == $uid", 
    ".read": "auth.uid == $uid", 
    "liked": { 
     "$heroIdx": { 
     ".validate": "newData.isString()" 
     } 
    } 
    } 
} 

In meinem Code ich die abonnieren möchten „mochte Helden“ ref, so dass das, was ich tue:

import { Injectable } from '@angular/core'; 
import { AngularFireDatabase } from 'angularfire2/database'; 
import { Observable } from 'rxjs/Observable'; 

import { AngularFireAuth } from 'angularfire2/auth'; 

@Injectable() 
export class UserFlagsService { 
    likedHeroes$: Observable<string[]>; 

    constructor(
    private afAuth: AngularFireAuth, 
    private db: AngularFireDatabase 
) { 
    this.likedHeroes$ = afAuth.authState.flatMap(user => { 
     return user && user.uid 
     ? this.db.list(`user_flags/${user.uid}/liked`) 
       .map(heroes => heroes.map(hero => <string>hero.$value)) 
     : Observable.of([]) 
    }); 
    } 
} 

Alles funktioniert gut, bis der Benutzer abmeldet ... Auch bei der Prüfung auf user und user.uid die Abfrage user_flags/MY_ID_HERE/liked scheint ausgelöst zu werden, und ich bekomme ein " Erlaubnis verweigert".

Ich habe versucht, für signout es abbestellen abonnieren und beobachten zu verwenden, aber hat nicht funktioniert entweder ... Die Abfrage wurde noch ausgelöst und konnte nicht mit „Zugriff verweigert“

Wie soll ich damit umgehen? Ich möchte, dass mein Service ein zuverlässiges Observable liefert, damit ich ihn in meinen Komponenten abonnieren kann.

Vielen Dank für Ihre Hilfe

Antwort

3

Ich gehe davon aus, dass Sie sicherstellen möchten, dass die Daten, die Sie in der Ansicht Rendering verschwindet auf Zeichen aus?

Wenn dies der Fall ist, würde ich vorschlagen, die switchMap operator from RXJS und das folgende Muster verwenden:

this.userProvider = this.afAuth.authState; 
this.likedHeroes$ = this.userProvider.switchMap((auth) => { 
    if(auth){ 
     return this.af.list('user_flags/' + auth.uid + '/liked'); 
    } 
}); 

Sie müssen Folgendes hinzufügen, um die switchMap Betreiber zu importieren:

import 'rxjs/add/operator/switchMap'; 

Hit me mit einige Kommentare, wenn Sie möchten, dass ich das etwas ausführlicher ausfülle oder wenn meine Annahme über das, was Sie erreichen wollen, falsch ist. Ich habe versucht, den besten Weg herauszufinden, wie ich dieses Zeug auch machen kann.

Sie sollten auch überprüfen, this video von der Angular Firebase YouTube, könnte es Ihnen helfen, mit einigen der Probleme in Ihrer Frage.

+0

Es kann auch helfen, den Unterschied zwischen flatMap und switchMap zu beachten, siehe: https://Stackoverflow.com/a/28180793/6288171 – nclarx

+0

Stil nicht bequem mit dem Unterschied zwischen flatMap und switchMap, aber das scheint sehr gut zu funktionieren . Danke – Maslow

+0

Wenn jemand das gleiche Problem mit angularfire2-offline hat, ist die Lösung die Methode 'reset()' zu verwenden, bevor 'this.afAuth.auth.signOut(); 'aufgerufen wird – Maslow

1

Ich konnte es durch einen BehaviorSubject Erstellen und abzumelden das Ereignis vor dem „signout“ ausgelöst zu arbeiten. Hier ist mein Anbieter:

import { Injectable } from '@angular/core'; 
import { AngularFireDatabase } from 'angularfire2/database'; 
import { Observable } from 'rxjs/Observable'; 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
import { Subscription } from 'rxjs/Subscription'; 

import { UserProvider } from '../../providers/user/user'; 

@Injectable() 
export class UserFlagsProvider { 
    likedHeroes$: Observable<string[]>; 
    subHeroesLiked: Subscription; 

    constructor(
    protected userProvider: UserProvider, 
    protected db: AngularFireDatabase 
) { 
    const heroesLikedSubject: BehaviorSubject<string[]> = new BehaviorSubject([]); 

    this.likedHeroes$ = heroesLikedSubject.asObservable(); 

    this.userProvider.user$.subscribe(user => { 
     if (user) { 
     this.subHeroesLiked = this.db.list(`user_flags/${user.uid}/liked`).subscribe(heroesSlugs => { 
      heroesLikedSubject.next(heroesSlugs.map(hero => <string>hero.$key)); 
     }); 
     } 
    }); 

    this.userProvider.signingOut$.subscribe(() => { 
     this.subHeroesLiked.unsubscribe(); 
    }); 
    } 
} 

Und mein userProvider

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 
import { AngularFireAuth } from 'angularfire2/auth'; 

@Injectable() 
export class UserProvider { 
    user$: Observable<firebase.User>; 
    user: firebase.User; 
    signingOut$: Subject<any> = new Subject(); 

    constructor(private afAuth: AngularFireAuth) { 
    this.user$ = afAuth.authState; 
    this.user$.subscribe(user => this.user = user); 
    } 

    // [...] 

    signout() { 
    this.signingOut$.next(); 

    return this.afAuth.auth.signOut(); 
    } 
} 

Hoffe, dass es jemand hilft.

FYI, dies funktioniert (vorerst) mit angularfire2-offline aus einem unbekannten Grund.

Wenn jemand einen besseren Weg sieht, es zu tun Ich bin interessiert

Verwandte Themen