Trying to use the latest version of Firebase and Angular. Overall concept I am trying to achieve is admin authentication. I have achieved login logout functions. I have saved the googleAuth login user to database with UID. Now what I am trying to do is restrict some pages to Logged in and Admin. So I have assigned isAdmin: true as a value in the user object that is stored in the database. Basically I want to see if the user is admin and return true or false for the router params. I have been using Angular and Firebase on and off. I would consider myself a beginner. I can't quite understand how to migrate from AngularFire2 4 -> AngularFire 5. The current error I am getting is TS2345:
ERROR in src/app/admin-auth-guard.service.ts(15,38): error TS2345: Argument of type '(user: User) => AngularFireObject<AppUser>' is not assignable to parameter of type '(value: User, index: number) => ObservableInput<{}>'.
Type 'AngularFireObject<AppUser>' is not assignable to type 'ObservableInput<{}>'.
Type 'AngularFireObject<AppUser>' is not assignable to type 'ArrayLike<{}>'.
Property 'length' is missing in type 'AngularFireObject<AppUser>'.
from what I think I understand the get function is returning an Object, but the error is expecting an observable. All I know about observables are that you can subscribe to them and you should destroy them...
I need to use currently logged in user id to query to database and return the user object matching the uid and then check to see if isAdmin is true or false. Then return that to the route params so I can restrict pages to Authenticated and Admin.
Please point me in the right direction.
admin-auth-guard.service.ts
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AdminAuthGuardService implements CanActivate {
constructor(private auth: AuthService, private userService: UserService) { }
canActivate(): Observable<boolean> {
return this.auth.user$.switchMap(user => this.userService.get(user.uid)).map(appUser => appUser.isAdmin);
}
}
user.service.ts
import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database';
import * as firebase from 'firebase';
import { Observable } from 'rxjs/Observable';
import { AppUser } from './models/app-user';
@Injectable()
export class UserService {
constructor(private db: AngularFireDatabase) { }
save(user: firebase.User) {
this.db.object('/users/' + user.uid).update({
name: user.displayName,
email: user.email
});
}
get(uid: string): AngularFireObject<AppUser> {
return this.db.object('/users/' + uid);
}
}
this is what I have been using for help: https://github.com/angular/angularfire2/blob/master/docs/version-5-upgrade.md
I don't understand how the annotations work exactly for the functions created. In reference to "observable" from this i assume means this canActivate() function extends from a Observable and should return a boolean (true/false).
Thank you for your time.
get(uid: string): Observable<any> {
return this.db.object('/users/' + uid).valueChanges();
}
And :
canActivate(): Observable<boolean> {
return this.auth.user$.switchMap(user =>
this.userService.get(user.uid)).map((appUser :any) => appUser.isAdmin);
}
For more information see : info