Angular:
8.1.2
Firebase:
6.3.1
AngularFire:
5.2.1
const onlyAllowSelf: AuthPipeGenerator = (next: ActivatedRouteSnapshot) => map((user: User) => !!user && next.params.userId === user.uid);
const routes: Routes = [
{ path: 'users/:id', component: UserComponent, ...canActivate(onlyAllowSelf)},
];
ERROR Error: Uncaught (in promise): TypeError: source.lift is not a function
TypeError: source.lift is not a function
at mapOperation (map.js:7)
at pipe.js:13
at Array.reduce ()
at piped (pipe.js:13)
at Observable.pipe (Observable.js:85)
at AngularFireAuthGuard.canActivate (auth-guard.js:22)
at router.js:4518
at Observable._subscribe (defer.js:8)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at resolvePromise (zone-evergreen.js:797)
at resolvePromise (zone-evergreen.js:754)
at zone-evergreen.js:858
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at drainMicroTaskQueue (zone-evergreen.js:559)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
at invokeTask (zone-evergreen.js:1603)
I was able to track this problem to https://github.com/angular/angularfire2/blob/992b15882c157d19f7779233e1d5e3da79cf0f03/src/auth-guard/auth-guard.ts#L28
This line seems to differentiate between an AuthPipeGenerator and an AuthPipe inputs by whether or not it has a name property, but if there is a named AuthPipeGenerator, like in my case or in your own docs then it tries to treat it as an AuthPipe, and fails
related: #2099
Workaround:
don't use canActivate. Use the full version:
{ path: 'users/:id', component: UserComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: onlyAllowSelf }},
@doom777 good catch on the root cause. It also seems the name check has trouble in some environments, I knew that might be a bit too magical. Will address in the next patch.
To be honest, the whole module is in bad shape. The doc claims that AuthPipe and AuthPipeGenerators are interchangeable, and you can provide either one both to authGuardPipe data parameter, or canActivate helper. In reality, as a direct parameter, you can only pass an AuthPipeGenerator or null (see: code, while canActivate tries to differentiate by name, assuming that unnamed functions are AuthPipeGenerator, and named functions are AuthPipe. Of course this means that
What's worse, is that I cannot think of a backwards compatible remedy. You simply cannot accept either a second order function (AuthPipeGenerator) or first order function (AuthPipe), and differentiate them at runtime, since at runtime they are both function type. And you can't call these functions and see if there is an error, because they are provided by user and may have side effects.
Workaround:
don't usecanActivate. Use the full version:{ path: 'users/:id', component: UserComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: onlyAllowSelf }},
For the record, with AngularFire v6, i don't seem to get those guards working as i want.
With the Helper (...canActivate) or not.
I followed the docs, and read quite a few issues there about that. But nothing on v6 seems documented.
In my app module, i have imported the AngularFireAuthModule & AngularFireAuthGuardModule.
I placed AngularFireAuthGuard in the providers array.
I just place the guards, then, it seems that they do nothing. Users can access roads as if the guards were not present.
_Side note: the routes i want to protect are lazy loaded as a Module._
Redirects are not triggered neither.
What's the status of the Guard Module in v6 ? Is there some way to active a kind of a "verbose" output in dev, so that we could see where the code starts to fail ?
Can't reproduce the issues after the recent changes, happy to accept PRs / new issues if things are still having trouble. Closing as outdated in the meantime.
Most helpful comment
To be honest, the whole module is in bad shape. The doc claims that AuthPipe and AuthPipeGenerators are interchangeable, and you can provide either one both to
authGuardPipedata parameter, orcanActivatehelper. In reality, as a direct parameter, you can only pass an AuthPipeGenerator or null (see: code, while canActivate tries to differentiate byname, assuming that unnamed functions are AuthPipeGenerator, and named functions are AuthPipe. Of course this means thatWhat's worse, is that I cannot think of a backwards compatible remedy. You simply cannot accept either a second order function (AuthPipeGenerator) or first order function (AuthPipe), and differentiate them at runtime, since at runtime they are both function type. And you can't call these functions and see if there is an error, because they are provided by user and may have side effects.