3

i'm stuck on this issue working on a ionic2 project with "firestore" service from firebase.

I have an osservable to get some data from firestore in a template using the async pipe. Rule on this EndPoint give read and write access only to logged user. When i sign-out i put a redirect to login page.

..and now come the issue..

when i land in the login page, after a few second, jump out the IonicErrorHandler notifying that i have insufficient permission.

so; how i can tell to firestore osservable; "hey dude, stop it, i call u later if someone log-in again"

(ill try an unsubscribe() befour the signOut but not work, and also
it does not from persistence)

Recapping:

when i logOut

    this.afAuth.auth.signOut();

the error:

 core.es5.js:1020 ERROR Error: Missing or insufficient permissions.
at new FirestoreError (error.js:164)
at JsonProtoSerializer.fromRpcStatus (serializer.js:126)
at JsonProtoSerializer.fromWatchChange (serializer.js:517)
at PersistentListenStream.onMessage (persistent_stream.js:334)
at persistent_stream.js:270
at persistent_stream.js:247
at async_queue.js:81
at t.invoke (polyfills.js:3)
at Object.onInvoke (core.es5.js:3890)
at t.invoke (polyfills.js:3)

(to be precise, i recive it 3 times. Exactly the number or of documents in the collection)

Service where i call the firestore endpoint:

export interface Attivita { 
  id: string;  
  committente: string; 
  durata: number; 
  nome: string; 
  progetto: string;
  userId: string;
}

@Injectable()
export class FirebaseService {

  attivitaCollectionRef: AngularFirestoreCollection<Attivita>;
  attivita$: Observable<Attivita[]>;

  constructor(private afs: AngularFirestore, 
              public afAuth: AngularFireAuth ) {

}

  setOsservableAttivita(uId){
    this.attivitaCollectionRef = this.afs.collection('attivita',  ref => {
        return ref.where("userId", "==", uId)
      });
      this.attivita$ = this.attivitaCollectionRef.snapshotChanges().map(actions => {
        return actions.map(action => {
          console.log(action)
          const data = action.payload.doc.data() as Attivita;
          const id = action.payload.doc.id;
          return { id, ...data };
        });
      });
  }

}

tks in advance to all help me to understand it :)

mrjungle
  • 31
  • 4

3 Answers3

4

I'd recommend watching the authState from Firebase and only taking from snapshotChanges while you're authenticated. The switchMap operator allows you to switch between observables based on conditions such as whether or not the user is authenticated. Here is an example of a possible solution.

// Assuming rxjs 5.5.0 with lettable operators

import { map } from 'rxjs/operators/map';
import { switchMap } from 'rxjs/operators/switchMap';
import { empty } from 'rxjs/observable/empty';
import { create } from 'rxjs/observable/create';

const actions$ = this.attivitaCollectionRef.snapshotChanges()
    .map(actions => {
        return actions.map(action => {
            console.log(action)
            const data = action.payload.doc.data() as Attivita;
            const id = action.payload.doc.id;
            return { id, ...data };
        });
    });
}),


this.attivita$ = create(
    // Listen for changes in the authState
    subscriber => this.afAuth.onAuthStateChanged(subscriber))
)
.pipe(

    // Determine if the user is logged in
    map(user => !!user),

    // switchMap will unsubscribe from the previous observable
    // so when isLoggedIn switches to false actions$ will be unsubscribed from
    switchMap(isLoggedIn => isLoggedIn ? actions$ : empty()),
);
adamduren
  • 3,857
  • 1
  • 14
  • 10
2

calling this after logout solved it for me:

afStore.firestore.disableNetwork();
AbdullahA
  • 113
  • 1
  • 8
1

Yes,

Normally this is solved by doing an unsubscribe of your subscription in the ngOnDestroy() of the component you are navigating away from. That's the way I do it.

So for you, that would be:

ngOnDestroy() {
      this.attivita$.unsubscribe();
}

However, it is very difficult to pinpoint which you should unsubscribe as the error does not give any indication on that.

I have added a question to the devs of angularFire on your issue:

https://github.com/angular/angularfire2/issues/1459.

It would be nice to have helped so that the exception points you in the right direction, for example, the path which was not unsubscribed or the last path segment.

Also, there are alternative methods for doing this listed in this post: http://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/

Hope that helps.

Lander
  • 61
  • 3