Search code examples
angularfirebasegoogle-cloud-firestoreangularfire2document

Not able to handle document data as I want in Angularfire2


I have a collection called 'users' with some dummy data like this:

uid: {
  admin: false,
  uid: 'longhash',
  displayName: 'User Name',
  email: 'user@email.com'
}

I'm having problems to handle retrieve and return the 'admin' data from the document, asyncronously.

My code:

  isAdmin:Observable<boolean> = this.uid.pipe(
switchMap(uid => {
  if(!uid){
    return observableOf(false);
  } else {

    let user = new BehaviorSubject<string>(uid);

    return user.pipe(
      switchMap(page =>
        this.afs.collection<User>('users', ref => ref.where('uid', '==', uid)).snapshotChanges().pipe(
          map(changes => {
            return changes.map(userData => {
              const cUser = userData.payload.doc.data() as User;
              return cUser ? cUser.admin : false;
            });
          })
        )
      )
    );
  }
})
);

This is the error my IDE shows: ide error return

Does anyone have any idea of what I'm doing wrong here?


Solution

  • In your switchMap operator, you are eather returning an observable emitting a boolean value or an observable emitting an array of boolean value, which doesn't correspond with the type declaration of the isAdmin constant const isAdmin:Observable<boolean>. Try something like this: isAdmin: Observable<boolean> | Observable<boolean[]>, it should fix the type error.

    If your goal is to return a boolean value and not a array of boolean value, assuming there's only one document in your user collection containing your uid, then try this:

    isAdmin:Observable<boolean> = this.uid.pipe(
    switchMap(uid => {
      if(!uid){
        return of(false);
      } else {
    
        return of(uid).pipe(
          switchMap(page =>
            this.afs.collection<User>('users', ref => ref.where('uid', '==', uid).limit(1)).snapshotChanges().pipe(
              map(changes => {
                return changes.map(userData => {
                  const cUser = userData.payload.doc.data() as User;
                  return cUser ? !!cUser.admin : false;
                })[0];
              })
            )
          )
        );
      }
    })
    );