【发布时间】:2017-03-19 09:08:22
【问题描述】:
我有一个带有数据服务的 Angular2 应用程序,它应该根据当前登录的用户显示不同的内容。 我的问题是我的身份验证服务在首次构建数据值后没有存储数据值,这使我无法访问其他数据提供者中的用户 ID。
这是我目前通过 2 个服务、1 个组件和 1 个 authguard 完成的工作(见下文)。我期望的逻辑是:
- Authguard 在收件箱路由激活之前调用
- Authguard 调用订阅 FirebaseAuth 的 AuthService 并设置 authState 变量
- 如果用户始终登录,DataService 应该具有来自 AuthService 的 authService.id 值
但是,发生的情况是 authService.id 产生 'Not set',因为即使用户已登录,它似乎也从未设置过。这可以通过在后面添加 console.log(state) 来证明在当前打印当前登录用户的 AuthService 中订阅 auth$。
因此,我的问题是变量 private authState 存储在 AuthService 中多久?在我的 DataService 中进行其他调用之前,是否有任何其他解决方案可以获取 authService.id 变量的可观察值?我能想到的一种解决方案是在 DataService 中为每个数据调用使用 switchmap,但这似乎不是最理想的。
AuthService
@Injectable()
export class AuthService {
private authState: FirebaseAuthState = null;
constructor(private af: AngularFire, public auth$: FirebaseAuth) {
auth$.subscribe((state: FirebaseAuthState) => {
this.authState = state;
});
}
get authenticated() {
return this.authState !== null;
}
get id(): string {
return this.authenticated ? this.authState.uid : 'Not set';
}
}
AuthGuard
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): Observable<boolean> {
return this.authService.auth$
.take(1)
.map(authState => !!authState)
.do(authenticated => {
if (!authenticated) {
this.router.navigate(['/compose']);
}
});
}
}
数据服务
@Injectable()
export class EmailService {
private emails: FirebaseListObservable<IEmail[]>;
private emailUserPath: string;
constructor(private af: AngularFire, authService: AuthService) {
this.emailUserPath = `/emails/${authService.id}`;
}
getAllEmails(): FirebaseListObservable<IEmail[]> {
return this.af.database.list(this.emailUserPath);
}
}
路由模块
const routes: Routes = [
{ path: 'inbox', component: InboxComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [ RouterModule.forChild(routes) ],
providers: [AuthGuard],
exports: [ RouterModule ]
})
export class EmailRoutingModule {}
应用模块
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { EmailsModule } from './emails/emails.module';
import { AppRoutingModule } from './app-routing.module';
import { AngularFireModule, AuthProviders, AuthMethods } from 'angularfire2';
import { UserSearchComponent } from './shared/user-search/user-search.component';
import {AuthService} from "./auth/auth.service";
import {AuthGuard} from "./auth/auth-guard";
import {EmailRoutingModule} from "./emails/email-routing.module";
import { UserOrLoginComponent } from './navigation/user-or-login/user-or-login.component';
import { NavigationListComponent } from './navigation/navigation-list/navigation-list.component';
export const firebaseConfig = {
apiKey: "hidden",
authDomain: "hidden",
databaseURL: "hidden",
storageBucket: "hidden"
};
const myFirebaseAuthConfig = {
provider: AuthProviders.Google,
method: AuthMethods.Popup
};
@NgModule({
declarations: [
AppComponent,
UserSearchComponent,
UserOrLoginComponent,
NavigationListComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule,
EmailRoutingModule,
AngularFireModule.initializeApp(firebaseConfig, myFirebaseAuthConfig),
EmailsModule // I include the Emails module below here
],
providers: [
AuthService,
AuthGuard
],
bootstrap: [AppComponent]
})
export class AppModule { }
电子邮件应用模块
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ComposeComponent } from './compose/compose.component';
import { EmailDetailComponent } from './email-detail/email-detail.component';
import { InboxComponent } from './inbox/inbox.component';
import { ReplyComponent } from './reply/reply.component';
import { ReplyListComponent } from './reply/reply-list/reply-list.component';
import { EmailService } from './shared/email.service';
import { FormsModule } from '@angular/forms';
import {ReplyService} from "./reply/reply.service";
@NgModule({
imports: [
CommonModule,
FormsModule
],
declarations: [
ComposeComponent,
EmailDetailComponent,
InboxComponent,
ReplyComponent,
ReplyListComponent
],
providers: [
EmailService,
ReplyService
]
})
export class EmailsModule { }
export { EmailService };
【问题讨论】:
-
您是否在
AppModule中提供AuthService以使其成为全局单例? -
我在一个单独的 auth 模块中提供它,然后我将它导入到应用程序模块中
标签: angular firebase firebase-authentication observable